/* XXX authorize does less here then in the REST path, e.g.,
        * the user's info is cached, but still incomplete */
       ldpp_dout(s, 2) << "authorizing" << dendl;
-      ret = req->authorize(op);
+      ret = req->authorize(op, null_yield);
       if (ret < 0) {
        dout(10) << "failed to authorize request" << dendl;
        abort_req(s, op, ret);
       }
 
       ldpp_dout(s, 2) << "reading op permissions" << dendl;
-      ret = req->read_permissions(op);
+      ret = req->read_permissions(op, null_yield);
       if (ret < 0) {
        abort_req(s, op, ret);
        goto done;
       }
 
       ldpp_dout(s, 2) << "init op" << dendl;
-      ret = op->init_processing();
+      ret = op->init_processing(null_yield);
       if (ret < 0) {
        abort_req(s, op, ret);
        goto done;
       }
 
       ldpp_dout(s, 2) << "verifying op permissions" << dendl;
-      ret = op->verify_permission();
+      ret = op->verify_permission(null_yield);
       if (ret < 0) {
        if (s->system_request) {
          dout(2) << "overriding permissions due to system operation" << dendl;
 
       ldpp_dout(s, 2) << "executing" << dendl;
       op->pre_exec();
-      op->execute();
+      op->execute(null_yield);
       op->complete();
 
     } catch (const ceph::crypto::DigestException& e) {
     /* XXX authorize does less here then in the REST path, e.g.,
      * the user's info is cached, but still incomplete */
     ldpp_dout(s, 2) << "authorizing" << dendl;
-    ret = req->authorize(op);
+    ret = req->authorize(op, null_yield);
     if (ret < 0) {
       dout(10) << "failed to authorize request" << dendl;
       abort_req(s, op, ret);
     }
 
     ldpp_dout(s, 2) << "reading op permissions" << dendl;
-    ret = req->read_permissions(op);
+    ret = req->read_permissions(op, null_yield);
     if (ret < 0) {
       abort_req(s, op, ret);
       goto done;
     }
 
     ldpp_dout(s, 2) << "init op" << dendl;
-    ret = op->init_processing();
+    ret = op->init_processing(null_yield);
     if (ret < 0) {
       abort_req(s, op, ret);
       goto done;
     }
 
     ldpp_dout(s, 2) << "verifying op permissions" << dendl;
-    ret = op->verify_permission();
+    ret = op->verify_permission(null_yield);
     if (ret < 0) {
       if (s->system_request) {
        dout(2) << "overriding permissions due to system operation" << dendl;
     return ret;
   }
 
-  int RGWLibRequest::read_permissions(RGWOp* op) {
+  int RGWLibRequest::read_permissions(RGWOp* op, optional_yield y) {
     /* bucket and object ops */
     int ret =
-      rgw_build_bucket_policies(rgwlib.get_store(), get_state());
+      rgw_build_bucket_policies(rgwlib.get_store(), get_state(), y);
     if (ret < 0) {
       ldout(get_state()->cct, 10) << "read_permissions (bucket policy) on "
                                  << get_state()->bucket << ":"
     } else if (! only_bucket()) {
       /* object ops */
       ret = rgw_build_object_policies(rgwlib.get_store(), get_state(),
-                                     op->prefetch_data());
+                                     op->prefetch_data(), y);
       if (ret < 0) {
        ldout(get_state()->cct, 10) << "read_permissions (object policy) on"
                                    << get_state()->bucket << ":"
     return ret;
   } /* RGWLibRequest::read_permissions */
 
-  int RGWHandler_Lib::authorize(const DoutPrefixProvider *dpp)
+  int RGWHandler_Lib::authorize(const DoutPrefixProvider *dpp, optional_yield y)
   {
     /* TODO: handle
      *  1. subusers
 
 }
 
 rgw::auth::Engine::result_t
-rgw::auth::Strategy::authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const
+rgw::auth::Strategy::authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const
 {
   result_t strategy_result = result_t::deny();
 
 
     result_t engine_result = result_t::deny();
     try {
-      engine_result = engine.authenticate(dpp, s);
+      engine_result = engine.authenticate(dpp, s, y);
     } catch (const int err) {
       engine_result = result_t::deny(err);
     }
 
 int
 rgw::auth::Strategy::apply(const DoutPrefixProvider *dpp, const rgw::auth::Strategy& auth_strategy,
-                           req_state* const s) noexcept
+                           req_state* const s, optional_yield y) noexcept
 {
   try {
-    auto result = auth_strategy.authenticate(dpp, s);
+    auto result = auth_strategy.authenticate(dpp, s, y);
     if (result.get_status() != decltype(result)::Status::GRANTED) {
       /* Access denied is acknowledged by returning a std::unique_ptr with
        * nullptr inside. */
 }
 
 rgw::auth::Engine::result_t
-rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const
+rgw::auth::AnonymousEngine::authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const
 {
   if (! is_applicable(s)) {
     return result_t::deny(-EPERM);
 
    *    interface.
    *
    * On error throws rgw::auth::Exception containing the reason. */
-  virtual result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s) const = 0;
+  virtual result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s, optional_yield y) const = 0;
 };
 
 
     FALLBACK,
   };
 
-  Engine::result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s) const override final;
+  Engine::result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s, optional_yield y) const override final;
 
   bool is_empty() const {
     return auth_stack.empty();
   }
 
-  static int apply(const DoutPrefixProvider* dpp, const Strategy& auth_strategy, req_state* s) noexcept;
+  static int apply(const DoutPrefixProvider* dpp, const Strategy& auth_strategy, req_state* s, optional_yield y) noexcept;
 
 private:
   /* Using the reference wrapper here to explicitly point out we are not
     return "rgw::auth::AnonymousEngine";
   }
 
-  Engine::result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s) const override final;
+  Engine::result_t authenticate(const DoutPrefixProvider* dpp, const req_state* s, optional_yield y) const override final;
 
 protected:
   virtual bool is_applicable(const req_state*) const noexcept {
 
 #include <boost/logic/tribool.hpp>
 #include <boost/optional.hpp>
 
+#include "rgw_service.h"
 #include "rgw_common.h"
 #include "rgw_auth.h"
+#include "rgw_user.h"
 
 namespace rgw {
 namespace auth {
 
     return "rgw::auth::keystone::TokenEngine";
   }
 
-  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override {
+  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
+                       optional_yield y) const override {
     return authenticate(dpp, extractor->get_token(s), s);
   }
 }; /* class TokenEngine */
 
   bucket_owner.set_name(user_info->display_name);
   if (bucket_exists) {
     ret = rgw_op_get_bucket_policy_from_attr(cct, store, bucket_info,
-                                             bucket_attrs, &old_policy);
+                                             bucket_attrs, &old_policy, null_yield);
     if (ret >= 0)  {
       if (old_policy.get_owner().get_id().compare(user) != 0) {
         return -EEXIST;
 
       goto done;
     }
 
-    op_ret = get_params();
+    op_ret = get_params(null_yield);
     if (op_ret < 0)
       goto done;
 
 
   class RGWFileHandle;
   class RGWWriteRequest;
 
-  static inline bool operator <(const struct timespec& lhs,
-                               const struct timespec& rhs) {
+  inline bool operator <(const struct timespec& lhs,
+                        const struct timespec& rhs) {
     if (lhs.tv_sec == rhs.tv_sec)
       return lhs.tv_nsec < rhs.tv_nsec;
     else
       return lhs.tv_sec < rhs.tv_sec;
   }
 
-  static inline bool operator ==(const struct timespec& lhs,
-                                const struct timespec& rhs) {
+  inline bool operator ==(const struct timespec& lhs,
+                         const struct timespec& rhs) {
     return ((lhs.tv_sec == rhs.tv_sec) &&
            (lhs.tv_nsec == rhs.tv_nsec));
   }
 
   WRITE_CLASS_ENCODER(RGWFileHandle);
 
-  static inline RGWFileHandle* get_rgwfh(struct rgw_file_handle* fh) {
+  inline RGWFileHandle* get_rgwfh(struct rgw_file_handle* fh) {
     return static_cast<RGWFileHandle*>(fh->fh_private);
   }
 
-  static inline enum rgw_fh_type fh_type_of(uint32_t flags) {
+  inline enum rgw_fh_type fh_type_of(uint32_t flags) {
     enum rgw_fh_type fh_type;
     switch(flags & RGW_LOOKUP_TYPE_FLAGS)
     {
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     limit = -1; /* no limit */
     return 0;
   }
               RGW_LOOKUP_FLAG_FILE);
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     max = default_max;
     return 0;
   }
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     max = default_max;
     return 0;
   }
 
   bool only_bucket() override { return false; }
 
-  int read_permissions(RGWOp* op_obj) override {
+  int read_permissions(RGWOp* op_obj, optional_yield) override {
     /* we ARE a 'create bucket' request (cf. rgw_rest.cc, ll. 1305-6) */
     return 0;
   }
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     struct req_state* state = get_state();
     RGWAccessControlPolicy_S3 s3policy(state->cct);
     /* we don't have (any) headers, so just create canned ACLs */
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     struct req_state* state = get_state();
     RGWAccessControlPolicy_S3 s3policy(state->cct);
     /* we don't have (any) headers, so just create canned ACLs */
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     return 0;
   }
 
     return 0;
   }
 
-  int send_response_data_error() override {
+  int send_response_data_error(optional_yield) override {
     /* S3 implementation just sends nothing--there is no side effect
      * to simulate here */
     return 0;
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     return 0;
   }
 
     return 0;
   }
 
-  int send_response_data_error() override {
+  int send_response_data_error(optional_yield) override {
     /* NOP */
     return 0;
   }
 
-  void execute() override {
-    RGWGetObj::execute();
+  void execute(optional_yield y) override {
+    RGWGetObj::execute(y);
     _size = get_state()->obj_size;
   }
 
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     max = default_max;
     return 0;
   }
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     struct req_state* state = get_state();
     RGWAccessControlPolicy_S3 s3policy(state->cct);
     /* we don't have (any) headers, so just create canned ACLs */
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     struct req_state* s = get_state();
     RGWAccessControlPolicy_S3 s3policy(s->cct);
     /* we don't have (any) headers, so just create canned ACLs */
     return 0;
   }
 
-  int get_params() override {
+  int get_params(optional_yield) override {
     return 0;
   }
 
     return 0;
   }
 
-  int get_params() override { return 0; }
+  int get_params(optional_yield) override { return 0; }
   bool only_bucket() override { return false; }
   void send_response() override {
     stats_req.kb = stats_op.kb;
 
     friend class RGWRESTMgr_Lib;
   public:
 
-    int authorize(const DoutPrefixProvider *dpp) override;
+    int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
 
     RGWHandler_Lib() {}
     ~RGWHandler_Lib() override {}
         tuser(std::move(_user)), cct(_cct)
       {}
 
-  int postauth_init() override { return 0; }
+  int postauth_init(optional_yield) override { return 0; }
 
     /* descendant equivalent of *REST*::init_from_header(...):
      * prepare request for execute()--should mean, fixup URI-alikes
 
     virtual bool only_bucket() = 0;
 
-    int read_permissions(RGWOp *op) override;
+    int read_permissions(RGWOp *op, optional_yield y) override;
 
   }; /* RGWLibRequest */
 
 
                                       rgw::sal::RGWStore *store,
                                       RGWBucketInfo& bucket_info,
                                       map<string, bufferlist>& bucket_attrs,
-                                      RGWAccessControlPolicy *policy)
+                                      RGWAccessControlPolicy *policy,
+                                      optional_yield y)
 {
   map<string, bufferlist>::iterator aiter = bucket_attrs.find(RGW_ATTR_ACL);
 
     ldout(cct, 0) << "WARNING: couldn't find acl header for bucket, generating default" << dendl;
     std::unique_ptr<rgw::sal::RGWUser> user = store->get_user(bucket_info.owner);
     /* object exists, but policy is broken */
-    int r = user->load_by_id(null_yield);
+    int r = user->load_by_id(y);
     if (r < 0)
       return r;
 
                               RGWBucketInfo& bucket_info,
                               map<string, bufferlist>& bucket_attrs,
                               RGWAccessControlPolicy *policy,
-                              rgw_bucket& bucket)
+                              rgw_bucket& bucket,
+                             optional_yield y)
 {
   if (!s->system_request && bucket_info.flags & BUCKET_SUSPENDED) {
     ldpp_dout(s, 0) << "NOTICE: bucket " << bucket_info.bucket.name
     return 0;
   }
 
-  int ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, policy);
+  int ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, policy, y);
   if (ret == -ENOENT) {
       ret = -ERR_NO_SUCH_BUCKET;
   }
                           boost::optional<Policy>& policy,
                            rgw::sal::RGWBucket* bucket,
                            rgw::sal::RGWObject* object,
+                          optional_yield y,
                            bool copy_src=false)
 {
   string upload_id;
     /* object does not exist checking the bucket's ACL to make sure
        that we send a proper error code */
     RGWAccessControlPolicy bucket_policy(s->cct);
-    ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, &bucket_policy);
+    ret = rgw_op_get_bucket_policy_from_attr(s->cct, store, bucket_info, bucket_attrs, &bucket_policy, y);
     if (ret < 0) {
       return ret;
     }
  * only_bucket: If true, reads the user and bucket ACLs rather than the object ACL.
  * Returns: 0 on success, -ERR# otherwise.
  */
-int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s)
+int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s, optional_yield y)
 {
   int ret = 0;
   auto obj_ctx = store->svc()->sysobj->init_obj_ctx();
     s->bucket_attrs = s->bucket->get_attrs();
     ret = read_bucket_policy(store, s, s->bucket->get_info(),
                             s->bucket->get_attrs(),
-                            s->bucket_acl.get(), s->bucket->get_key());
+                            s->bucket_acl.get(), s->bucket->get_key(), y);
     acct_acl_user = {
       s->bucket->get_info().owner,
       s->bucket_acl->get_owner().get_display_name(),
  * Returns: 0 on success, -ERR# otherwise.
  */
 int rgw_build_object_policies(rgw::sal::RGWRadosStore *store, struct req_state *s,
-                             bool prefetch_data)
+                             bool prefetch_data, optional_yield y)
 {
   int ret = 0;
 
     }
     ret = read_obj_policy(store, s, s->bucket->get_info(), s->bucket_attrs,
                          s->object_acl.get(), nullptr, s->iam_policy, s->bucket.get(),
-                          s->object.get());
+                          s->object.get(), y);
   }
 
   return ret;
 }
 
 
-int RGWGetObj::verify_permission()
+int RGWGetObj::verify_permission(optional_yield y)
 {
   s->object->set_atomic(s->obj_ctx);
 
   return 0;
 }
 
-int RGWGetObjTags::verify_permission()
+int RGWGetObjTags::verify_permission(optional_yield y)
 {
   auto iam_action = s->object->get_instance().empty()?
     rgw::IAM::s3GetObjectTagging:
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetObjTags::execute()
+void RGWGetObjTags::execute(optional_yield y)
 {
   rgw::sal::RGWAttrs attrs;
 
   send_response_data(tags_bl);
 }
 
-int RGWPutObjTags::verify_permission()
+int RGWPutObjTags::verify_permission(optional_yield y)
 {
   auto iam_action = s->object->get_instance().empty() ?
     rgw::IAM::s3PutObjectTagging:
   return 0;
 }
 
-void RGWPutObjTags::execute()
+void RGWPutObjTags::execute(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
 }
 
 
-int RGWDeleteObjTags::verify_permission()
+int RGWDeleteObjTags::verify_permission(optional_yield y)
 {
   if (!rgw::sal::RGWObject::empty(s->object.get())) {
     auto iam_action = s->object->get_instance().empty() ?
   return 0;
 }
 
-void RGWDeleteObjTags::execute()
+void RGWDeleteObjTags::execute(optional_yield y)
 {
   if (rgw::sal::RGWObject::empty(s->object.get()))
     return;
   op_ret = s->object->delete_obj_attrs(s->obj_ctx, RGW_ATTR_TAGS, s->yield);
 }
 
-int RGWGetBucketTags::verify_permission()
+int RGWGetBucketTags::verify_permission(optional_yield y)
 {
 
   if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketTagging)) {
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetBucketTags::execute() 
+void RGWGetBucketTags::execute(optional_yield y)
 {
   auto iter = s->bucket_attrs.find(RGW_ATTR_TAGS);
   if (iter != s->bucket_attrs.end()) {
   send_response_data(tags_bl);
 }
 
-int RGWPutBucketTags::verify_permission() {
+int RGWPutBucketTags::verify_permission(optional_yield y) {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketTagging);
 }
 
-void RGWPutBucketTags::execute() {
+void RGWPutBucketTags::execute(optional_yield y)
+{
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) 
     return;
 
   rgw_bucket_object_pre_exec(s);
 }
 
-int RGWDeleteBucketTags::verify_permission()
+int RGWDeleteBucketTags::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketTagging);
 }
 
-void RGWDeleteBucketTags::execute()
+void RGWDeleteBucketTags::execute(optional_yield y)
 {
   bufferlist in_data;
   op_ret = store->forward_request_to_master(s->user.get(), nullptr, in_data, nullptr, s->info);
   });
 }
 
-int RGWGetBucketReplication::verify_permission()
+int RGWGetBucketReplication::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3GetReplicationConfiguration)) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetBucketReplication::execute()
+void RGWGetBucketReplication::execute(optional_yield y)
 {
   send_response_data();
 }
 
-int RGWPutBucketReplication::verify_permission() {
+int RGWPutBucketReplication::verify_permission(optional_yield y) {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutReplicationConfiguration);
 }
 
-void RGWPutBucketReplication::execute() {
+void RGWPutBucketReplication::execute(optional_yield y) {
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) 
     return;
 
   rgw_bucket_object_pre_exec(s);
 }
 
-int RGWDeleteBucketReplication::verify_permission()
+int RGWDeleteBucketReplication::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3DeleteReplicationConfiguration);
 }
 
-void RGWDeleteBucketReplication::execute()
+void RGWDeleteBucketReplication::execute(optional_yield y)
 {
   bufferlist in_data;
   op_ret = store->forward_request_to_master(s->user.get(), nullptr, in_data, nullptr, s->info);
                                                  off_t end_ofs,
                                                  void *param,
                                                  bool swift_slo),
-                                       void * const cb_param)
+                                       void * const cb_param,
+                                      optional_yield y)
 {
   uint64_t obj_ofs = 0, len_count = 0;
   bool found_start = false, found_end = false, handled_end = false;
   rgw::sal::RGWBucket::ListResults results;
   MD5 etag_sum;
   do {
-#define MAX_LIST_OBJS 100
-    int r = bucket->list(params, MAX_LIST_OBJS, results, null_yield);
+    static constexpr auto MAX_LIST_OBJS = 100u;
+    int r = bucket->list(params, MAX_LIST_OBJS, results, y);
     if (r < 0) {
       return r;
     }
     bucket, ent, bucket_acl, bucket_policy, start_ofs, end_ofs, swift_slo);
 }
 
-int RGWGetObj::handle_user_manifest(const char *prefix)
+int RGWGetObj::handle_user_manifest(const char *prefix, optional_yield y)
 {
   const std::string_view prefix_view(prefix);
   ldpp_dout(this, 2) << "RGWGetObj::handle_user_manifest() prefix="
       return r;
     }
     bucket_acl = &_bucket_acl;
-    r = read_bucket_policy(store, s, ubucket->get_info(), bucket_attrs, bucket_acl, ubucket->get_key());
+    r = read_bucket_policy(store, s, ubucket->get_info(), bucket_attrs, bucket_acl, ubucket->get_key(), y);
     if (r < 0) {
       ldpp_dout(this, 0) << "failed to read bucket policy" << dendl;
       return r;
   r = iterate_user_manifest_parts(s->cct, store, ofs, end,
         pbucket, obj_prefix, bucket_acl, *bucket_policy,
         nullptr, &s->obj_size, &lo_etag,
-        nullptr /* cb */, nullptr /* cb arg */);
+       nullptr /* cb */, nullptr /* cb arg */, y);
   if (r < 0) {
     return r;
   }
   r = iterate_user_manifest_parts(s->cct, store, ofs, end,
         pbucket, obj_prefix, bucket_acl, *bucket_policy,
         &total_len, nullptr, nullptr,
-        nullptr, nullptr);
+       nullptr, nullptr, y);
   if (r < 0) {
     return r;
   }
   r = iterate_user_manifest_parts(s->cct, store, ofs, end,
         pbucket, obj_prefix, bucket_acl, *bucket_policy,
         nullptr, nullptr, nullptr,
-        get_obj_user_manifest_iterate_cb, (void *)this);
+       get_obj_user_manifest_iterate_cb, (void *)this, y);
   if (r < 0) {
     return r;
   }
   return r;
 }
 
-int RGWGetObj::handle_slo_manifest(bufferlist& bl)
+int RGWGetObj::handle_slo_manifest(bufferlist& bl, optional_yield y)
 {
   RGWSLOInfo slo_info;
   auto bliter = bl.cbegin();
         bucket = tmp_bucket.get();
         bucket_acl = &_bucket_acl;
         r = read_bucket_policy(store, s, tmp_bucket->get_info(), tmp_bucket->get_attrs(), bucket_acl,
-                               tmp_bucket->get_key());
+                               tmp_bucket->get_key(), y);
         if (r < 0) {
           ldpp_dout(this, 0) << "failed to read bucket ACL for bucket "
                            << bucket << dendl;
   }
 }
 
-void RGWGetObj::execute()
+void RGWGetObj::execute(optional_yield y)
 {
   bufferlist bl;
   gc_invalidate_time = ceph_clock_now();
 
   std::unique_ptr<rgw::sal::RGWObject::ReadOp> read_op(s->object->get_read_op(s->obj_ctx));
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     goto done_err;
 
 
   attr_iter = attrs.find(RGW_ATTR_USER_MANIFEST);
   if (attr_iter != attrs.end() && !skip_manifest) {
-    op_ret = handle_user_manifest(attr_iter->second.c_str());
+    op_ret = handle_user_manifest(attr_iter->second.c_str(), y);
     if (op_ret < 0) {
       ldpp_dout(this, 0) << "ERROR: failed to handle user manifest ret="
                       << op_ret << dendl;
   attr_iter = attrs.find(RGW_ATTR_SLO_MANIFEST);
   if (attr_iter != attrs.end() && !skip_manifest) {
     is_slo = true;
-    op_ret = handle_slo_manifest(attr_iter->second);
+    op_ret = handle_slo_manifest(attr_iter->second, y);
     if (op_ret < 0) {
       ldpp_dout(this, 0) << "ERROR: failed to handle slo manifest ret=" << op_ret
                       << dendl;
   return;
 
 done_err:
-  send_response_data_error();
+  send_response_data_error(y);
 }
 
 int RGWGetObj::init_common()
   return 0;
 }
 
-int RGWListBuckets::verify_permission()
+int RGWListBuckets::verify_permission(optional_yield y)
 {
   rgw::Partition partition = rgw::Partition::aws;
   rgw::Service service = rgw::Service::s3;
   return 0;
 }
 
-int RGWGetUsage::verify_permission()
+int RGWGetUsage::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return 0;
 }
 
-void RGWListBuckets::execute()
+void RGWListBuckets::execute(optional_yield y)
 {
   bool done;
   bool started = false;
 
   const uint64_t max_buckets = s->cct->_conf->rgw_list_buckets_max_chunk;
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     goto send_end;
   }
       read_count = max_buckets;
     }
 
-    op_ret = s->user->list_buckets(marker, end_marker, read_count, should_get_stats(), buckets, null_yield);
+    op_ret = s->user->list_buckets(marker, end_marker, read_count, should_get_stats(), buckets, y);
 
     if (op_ret < 0) {
       /* hmm.. something wrong here.. the user was authenticated, so it
   send_response_end();
 }
 
-void RGWGetUsage::execute()
+void RGWGetUsage::execute(optional_yield y)
 {
   uint64_t start_epoch = 0;
   uint64_t end_epoch = (uint64_t)-1;
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
     
     }    
   }
 
-  op_ret = rgw_user_sync_all_stats(store, s->user->get_id(), null_yield);
+  op_ret = rgw_user_sync_all_stats(store, s->user->get_id(), y);
   if (op_ret < 0) {
     ldpp_dout(this, 0) << "ERROR: failed to sync user stats" << dendl;
     return;
   }
 
-  op_ret = rgw_user_get_all_buckets_stats(store, s->user->get_id(), buckets_usage, null_yield);
+  op_ret = rgw_user_get_all_buckets_stats(store, s->user->get_id(), buckets_usage, y);
   if (op_ret < 0) {
     ldpp_dout(this, 0) << "ERROR: failed to get user's buckets stats" << dendl;
     return;
   }
 
-  op_ret = store->ctl()->user->read_stats(s->user->get_id(), &stats, null_yield);
+  op_ret = store->ctl()->user->read_stats(s->user->get_id(), &stats, y);
   if (op_ret < 0) {
     ldpp_dout(this, 0) << "ERROR: can't read user header"  << dendl;
     return;
   return;
 }
 
-int RGWStatAccount::verify_permission()
+int RGWStatAccount::verify_permission(optional_yield y)
 {
   if (!verify_user_permission_no_policy(this, s, RGW_PERM_READ)) {
     return -EACCES;
   return 0;
 }
 
-void RGWStatAccount::execute()
+void RGWStatAccount::execute(optional_yield y)
 {
   string marker;
   rgw::sal::RGWBucketList buckets;
 
     lastmarker = nullptr;
     op_ret = rgw_read_user_buckets(store, s->user->get_id(), buckets, marker,
-                                  string(), max_buckets, true, null_yield);
+                                  string(), max_buckets, true, y);
     if (op_ret < 0) {
       /* hmm.. something wrong here.. the user was authenticated, so it
          should exist */
   } while (buckets.is_truncated());
 }
 
-int RGWGetBucketVersioning::verify_permission()
+int RGWGetBucketVersioning::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketVersioning);
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetBucketVersioning::execute()
+void RGWGetBucketVersioning::execute(optional_yield y)
 {
   if (! s->bucket_exists) {
     op_ret = -ERR_NO_SUCH_BUCKET;
   mfa_enabled = s->bucket->get_info().mfa_enabled();
 }
 
-int RGWSetBucketVersioning::verify_permission()
+int RGWSetBucketVersioning::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketVersioning);
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWSetBucketVersioning::execute()
+void RGWSetBucketVersioning::execute(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
   }
 }
 
-int RGWGetBucketWebsite::verify_permission()
+int RGWGetBucketWebsite::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketWebsite);
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetBucketWebsite::execute()
+void RGWGetBucketWebsite::execute(optional_yield y)
 {
   if (!s->bucket->get_info().has_website) {
     op_ret = -ERR_NO_SUCH_WEBSITE_CONFIGURATION;
   }
 }
 
-int RGWSetBucketWebsite::verify_permission()
+int RGWSetBucketWebsite::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketWebsite);
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWSetBucketWebsite::execute()
+void RGWSetBucketWebsite::execute(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
 
   if (op_ret < 0)
     return;
   }
 }
 
-int RGWDeleteBucketWebsite::verify_permission()
+int RGWDeleteBucketWebsite::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3DeleteBucketWebsite);
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWDeleteBucketWebsite::execute()
+void RGWDeleteBucketWebsite::execute(optional_yield y)
 {
   bufferlist in_data;
 
   }
 }
 
-int RGWStatBucket::verify_permission()
+int RGWStatBucket::verify_permission(optional_yield y)
 {
   // This (a HEAD request on a bucket) is governed by the s3:ListBucket permission.
   if (!verify_bucket_permission(this, s, rgw::IAM::s3ListBucket)) {
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWStatBucket::execute()
+void RGWStatBucket::execute(optional_yield y)
 {
   if (!s->bucket_exists) {
     op_ret = -ERR_NO_SUCH_BUCKET;
   op_ret = bucket->update_container_stats();
 }
 
-int RGWListBucket::verify_permission()
+int RGWListBucket::verify_permission(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     return op_ret;
   }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWListBucket::execute()
+void RGWListBucket::execute(optional_yield y)
 {
   if (!s->bucket_exists) {
     op_ret = -ERR_NO_SUCH_BUCKET;
   }
 }
 
-int RGWGetBucketLogging::verify_permission()
+int RGWGetBucketLogging::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketLogging);
 }
 
-int RGWGetBucketLocation::verify_permission()
+int RGWGetBucketLocation::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketLocation);
 }
 
-int RGWCreateBucket::verify_permission()
+int RGWCreateBucket::verify_permission(optional_yield y)
 {
   /* This check is mostly needed for S3 that doesn't support account ACL.
    * Swift doesn't allow to delegate any permission to an anonymous user,
     string marker;
     op_ret = rgw_read_user_buckets(store, s->user->get_id(), buckets,
                                   marker, string(), s->user->get_max_buckets(),
-                                  false, null_yield);
+                                  false, y);
     if (op_ret < 0) {
       return op_ret;
     }
 }
 
 
-void RGWCreateBucket::execute()
+void RGWCreateBucket::execute(optional_yield y)
 {
   buffer::list aclbl;
   buffer::list corsbl;
   string bucket_name = rgw_make_bucket_entry_name(s->bucket_tenant, s->bucket_name);
   rgw_raw_obj obj(store->svc()->zone->get_zone_params().domain_root, bucket_name);
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
                                info.swift_ver_location,
                                pquota_info, policy, attrs, info, ep_objv,
                                true, obj_lock_enabled, &s->bucket_exists, s->info,
-                               &s->bucket, null_yield);
+                               &s->bucket, y);
 
   /* continue if EEXIST and create_bucket will fail below.  this way we can
    * recover from a partial create by retrying it. */
   }
 }
 
-int RGWDeleteBucket::verify_permission()
+int RGWDeleteBucket::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3DeleteBucket)) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWDeleteBucket::execute()
+void RGWDeleteBucket::execute(optional_yield y)
 {
   if (s->bucket_name.empty()) {
     op_ret = -EINVAL;
     }
   }
 
-  op_ret = s->bucket->sync_user_stats(null_yield);
+  op_ret = s->bucket->sync_user_stats(y);
   if ( op_ret < 0) {
      ldpp_dout(this, 1) << "WARNING: failed to sync user stats before bucket delete: op_ret= " << op_ret << dendl;
   }
   return;
 }
 
-int RGWPutObj::init_processing() {
+int RGWPutObj::init_processing(optional_yield y) {
   copy_source = url_decode(s->info.env->get("HTTP_X_AMZ_COPY_SOURCE", ""));
   copy_source_range = s->info.env->get("HTTP_X_AMZ_COPY_SOURCE_RANGE");
   map<string, bufferlist> src_attrs;
     }
 
   } /* copy_source */
-  return RGWOp::init_processing();
+  return RGWOp::init_processing(y);
 }
 
-int RGWPutObj::verify_permission()
+int RGWPutObj::verify_permission(optional_yield y)
 {
   if (! copy_source.empty()) {
 
 
     /* check source object permissions */
     if (read_obj_policy(store, s, copy_source_bucket_info, cs_attrs, &cs_acl, nullptr,
-                       policy, cs_bucket.get(), cs_object.get(), true) < 0) {
+                       policy, cs_bucket.get(), cs_object.get(), y, true) < 0) {
       return -EACCES;
     }
 
       return -EACCES;
   }
 
-  auto op_ret = get_params();
+  auto op_ret = get_params(y);
   if (op_ret < 0) {
     ldpp_dout(this, 20) << "get_params() returned ret=" << op_ret << dendl;
     return op_ret;
   return Compressor::create(s->cct, alg);
 }
 
-void RGWPutObj::execute()
+void RGWPutObj::execute(optional_yield y)
 {
   char supplied_md5_bin[CEPH_CRYPTO_MD5_DIGESTSIZE + 1];
   char supplied_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
 
   if (!chunked_upload) { /* with chunked upload we don't know how big is the upload.
                             we also check sizes at the end anyway */
-    op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->content_length, null_yield);
+    op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->content_length, y);
     if (op_ret < 0) {
       ldpp_dout(this, 20) << "check_quota() returned ret=" << op_ret << dendl;
       return;
     return;
   }
 
-  op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->obj_size, null_yield);
+  op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->obj_size, y);
   if (op_ret < 0) {
     ldpp_dout(this, 20) << "second check_quota() returned op_ret=" << op_ret << dendl;
     return;
   }
 }
 
-int RGWPostObj::verify_permission()
+int RGWPostObj::verify_permission(optional_yield y)
 {
   return 0;
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWPostObj::execute()
+void RGWPostObj::execute(optional_yield y)
 {
   boost::optional<RGWPutObj_Compress> compressor;
   CompressorRef plugin;
   char supplied_md5[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
 
   /* Read in the data from the POST form. */
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     return;
   }
     ceph::buffer::list bl, aclbl;
     int len = 0;
 
-    op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->content_length, null_yield);
+    op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->content_length, y);
     if (op_ret < 0) {
       return;
     }
     s->object->set_obj_size(ofs);
 
 
-    op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->obj_size, null_yield);
+    op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->obj_size, y);
     if (op_ret < 0) {
       return;
     }
   }
 }
 
-int RGWPutMetadataAccount::init_processing()
+int RGWPutMetadataAccount::init_processing(optional_yield y)
 {
   /* First, go to the base class. At the time of writing the method was
    * responsible only for initializing the quota. This isn't necessary
    * here as we are touching metadata only. I'm putting this call only
    * for the future. */
-  op_ret = RGWOp::init_processing();
+  op_ret = RGWOp::init_processing(y);
   if (op_ret < 0) {
     return op_ret;
   }
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     return op_ret;
   }
   return 0;
 }
 
-int RGWPutMetadataAccount::verify_permission()
+int RGWPutMetadataAccount::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return 0;
 }
 
-void RGWPutMetadataAccount::execute()
+void RGWPutMetadataAccount::execute(optional_yield y)
 {
   /* Params have been extracted earlier. See init_processing(). */
   RGWUserInfo new_uinfo;
                                        .set_attrs(&attrs));
 }
 
-int RGWPutMetadataBucket::verify_permission()
+int RGWPutMetadataBucket::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission_no_policy(this, s, RGW_PERM_WRITE)) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWPutMetadataBucket::execute()
+void RGWPutMetadataBucket::execute(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     return;
   }
     });
 }
 
-int RGWPutMetadataObject::verify_permission()
+int RGWPutMetadataObject::verify_permission(optional_yield y)
 {
   // This looks to be something specific to Swift. We could add
   // operations like swift:PutMetadataObject to the Policy Engine.
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWPutMetadataObject::execute()
+void RGWPutMetadataObject::execute(optional_yield y)
 {
   rgw_obj target_obj;
   rgw::sal::RGWAttrs attrs, rmattrs;
 
   s->object->set_atomic(s->obj_ctx);
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     return;
   }
   op_ret = s->object->set_obj_attrs(s->obj_ctx, &attrs, &rmattrs, s->yield, &target_obj);
 }
 
-int RGWDeleteObj::handle_slo_manifest(bufferlist& bl)
+int RGWDeleteObj::handle_slo_manifest(bufferlist& bl, optional_yield y)
 {
   RGWSLOInfo slo_info;
   auto bliter = bl.cbegin();
   path.obj_key = s->object->get_key();
   items.push_back(path);
 
-  int ret = deleter->delete_chunk(items);
+  int ret = deleter->delete_chunk(items, y);
   if (ret < 0) {
     return ret;
   }
   return 0;
 }
 
-int RGWDeleteObj::verify_permission()
+int RGWDeleteObj::verify_permission(optional_yield y)
 {
-  int op_ret = get_params();
+  int op_ret = get_params(y);
   if (op_ret) {
     return op_ret;
   }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWDeleteObj::execute()
+void RGWDeleteObj::execute(optional_yield y)
 {
   if (!s->bucket_exists) {
     op_ret = -ERR_NO_SUCH_BUCKET;
       const auto slo_attr = attrs.find(RGW_ATTR_SLO_MANIFEST);
 
       if (slo_attr != attrs.end()) {
-        op_ret = handle_slo_manifest(slo_attr->second);
+        op_ret = handle_slo_manifest(slo_attr->second, y);
         if (op_ret < 0) {
           ldpp_dout(this, 0) << "ERROR: failed to handle slo manifest ret=" << op_ret << dendl;
         }
   return true;
 }
 
-int RGWCopyObj::verify_permission()
+int RGWCopyObj::verify_permission(optional_yield y)
 {
   RGWAccessControlPolicy src_acl(s->cct);
   boost::optional<Policy> src_policy;
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return op_ret;
 
 
     /* check source object permissions */
     op_ret = read_obj_policy(store, s, src_bucket->get_info(), src_bucket->get_attrs(), &src_acl, &src_placement.storage_class,
-                            src_policy, src_bucket.get(), src_object.get());
+                            src_policy, src_bucket.get(), src_object.get(), y);
     if (op_ret < 0) {
       return op_ret;
     }
   /* check dest bucket permissions */
   op_ret = read_bucket_policy(store, s, dest_bucket->get_info(),
                              dest_bucket->get_attrs(),
-                              &dest_bucket_policy, dest_bucket->get_key());
+                              &dest_bucket_policy, dest_bucket->get_key(), y);
   if (op_ret < 0) {
     return op_ret;
   }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWCopyObj::execute()
+void RGWCopyObj::execute(optional_yield y)
 {
   if (init_common() < 0)
     return;
     }
     // enforce quota against the destination bucket owner
     op_ret = dest_bucket->check_quota(user_quota, bucket_quota,
-                                     astate->accounted_size, null_yield);
+                                     astate->accounted_size, y);
     if (op_ret < 0) {
       return;
     }
   }
 }
 
-int RGWGetACLs::verify_permission()
+int RGWGetACLs::verify_permission(optional_yield y)
 {
   bool perm;
   if (!rgw::sal::RGWObject::empty(s->object.get())) {
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetACLs::execute()
+void RGWGetACLs::execute(optional_yield y)
 {
   stringstream ss;
   RGWAccessControlPolicy* const acl = \
 
 
 
-int RGWPutACLs::verify_permission()
+int RGWPutACLs::verify_permission(optional_yield y)
 {
   bool perm;
 
   return 0;
 }
 
-int RGWGetLC::verify_permission()
+int RGWGetLC::verify_permission(optional_yield y)
 {
   bool perm;
   perm = verify_bucket_permission(this, s, rgw::IAM::s3GetLifecycleConfiguration);
   return 0;
 }
 
-int RGWPutLC::verify_permission()
+int RGWPutLC::verify_permission(optional_yield y)
 {
   bool perm;
   perm = verify_bucket_permission(this, s, rgw::IAM::s3PutLifecycleConfiguration);
   return 0;
 }
 
-int RGWDeleteLC::verify_permission()
+int RGWDeleteLC::verify_permission(optional_yield y)
 {
   bool perm;
   perm = verify_bucket_permission(this, s, rgw::IAM::s3PutLifecycleConfiguration);
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWPutACLs::execute()
+void RGWPutACLs::execute(optional_yield y)
 {
   bufferlist bl;
 
 
   owner = existing_policy->get_owner();
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     if (op_ret == -ERANGE) {
       ldpp_dout(this, 4) << "The size of request xml data is larger than the max limitation, data size = "
   }
 }
 
-void RGWPutLC::execute()
+void RGWPutLC::execute(optional_yield y)
 {
   bufferlist bl;
   
     return;
   }
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
   return;
 }
 
-void RGWDeleteLC::execute()
+void RGWDeleteLC::execute(optional_yield y)
 {
   bufferlist data;
   op_ret = store->forward_request_to_master(s->user.get(), nullptr, data, nullptr, s->info);
   return;
 }
 
-int RGWGetCORS::verify_permission()
+int RGWGetCORS::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketCORS);
 }
 
-void RGWGetCORS::execute()
+void RGWGetCORS::execute(optional_yield y)
 {
   op_ret = read_bucket_cors();
   if (op_ret < 0)
   }
 }
 
-int RGWPutCORS::verify_permission()
+int RGWPutCORS::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketCORS);
 }
 
-void RGWPutCORS::execute()
+void RGWPutCORS::execute(optional_yield y)
 {
   rgw_raw_obj obj;
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
     });
 }
 
-int RGWDeleteCORS::verify_permission()
+int RGWDeleteCORS::verify_permission(optional_yield y)
 {
   // No separate delete permission
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketCORS);
 }
 
-void RGWDeleteCORS::execute()
+void RGWDeleteCORS::execute(optional_yield y)
 {
   bufferlist data;
   op_ret = store->forward_request_to_master(s->user.get(), nullptr, data, nullptr, s->info);
   return 0;
 }
 
-void RGWOptionsCORS::execute()
+void RGWOptionsCORS::execute(optional_yield y)
 {
   op_ret = read_bucket_cors();
   if (op_ret < 0)
   return;
 }
 
-int RGWGetRequestPayment::verify_permission()
+int RGWGetRequestPayment::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketRequestPayment);
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetRequestPayment::execute()
+void RGWGetRequestPayment::execute(optional_yield y)
 {
   requester_pays = s->bucket->get_info().requester_pays;
 }
 
-int RGWSetRequestPayment::verify_permission()
+int RGWSetRequestPayment::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketRequestPayment);
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWSetRequestPayment::execute()
+void RGWSetRequestPayment::execute(optional_yield y)
 {
 
   op_ret = store->forward_request_to_master(s->user.get(), nullptr, in_data, nullptr, s->info);
     return;
   }
 
-  op_ret = get_params();
+  op_ret = get_params(y);
 
   if (op_ret < 0)
     return;
   s->bucket_attrs = s->bucket->get_attrs();
 }
 
-int RGWInitMultipart::verify_permission()
+int RGWInitMultipart::verify_permission(optional_yield y)
 {
   if (s->iam_policy || ! s->iam_user_policies.empty()) {
     auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env,
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWInitMultipart::execute()
+void RGWInitMultipart::execute(optional_yield y)
 {
   bufferlist aclbl;
   map<string, bufferlist> attrs;
   rgw_obj obj;
 
-  if (get_params() < 0)
+  if (get_params(y) < 0)
     return;
 
   if (rgw::sal::RGWObject::empty(s->object.get()))
   }
 }
 
-int RGWCompleteMultipart::verify_permission()
+int RGWCompleteMultipart::verify_permission(optional_yield y)
 {
   if (s->iam_policy || ! s->iam_user_policies.empty()) {
     auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env,
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWCompleteMultipart::execute()
+void RGWCompleteMultipart::execute(optional_yield y)
 {
   RGWMultiCompleteUpload *parts;
   map<int, string>::iterator iter;
   RGWObjManifest manifest;
   uint64_t olh_epoch = 0;
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
   op_ret = get_system_versioning_params(s, &olh_epoch, &version_id);
                           meta_obj->get_obj(), &meta_pool);
   store->getRados()->open_pool_ctx(meta_pool, serializer.ioctx, true);
 
-  op_ret = serializer.try_lock(raw_obj.oid, dur);
+  op_ret = serializer.try_lock(raw_obj.oid, dur, y);
   if (op_ret < 0) {
     ldpp_dout(this, 0) << "failed to acquire lock" << dendl;
     op_ret = -ERR_INTERNAL_ERROR;
 
 int RGWCompleteMultipart::MPSerializer::try_lock(
   const std::string& _oid,
-  utime_t dur)
+  utime_t dur, optional_yield y)
 {
   oid = _oid;
   op.assert_exists();
   lock.set_duration(dur);
   lock.lock_exclusive(&op);
-  int ret = rgw_rados_operate(ioctx, oid, &op, null_yield);
+  int ret = rgw_rados_operate(ioctx, oid, &op, y);
   if (! ret) {
     locked = true;
   }
   send_response();
 }
 
-int RGWAbortMultipart::verify_permission()
+int RGWAbortMultipart::verify_permission(optional_yield y)
 {
   if (s->iam_policy || ! s->iam_user_policies.empty()) {
     auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env,
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWAbortMultipart::execute()
+void RGWAbortMultipart::execute(optional_yield y)
 {
   op_ret = -EINVAL;
   string upload_id;
   op_ret = abort_multipart_upload(store, s->cct, obj_ctx, s->bucket->get_info(), mp);
 }
 
-int RGWListMultipart::verify_permission()
+int RGWListMultipart::verify_permission(optional_yield y)
 {
   if (!verify_object_permission(this, s, rgw::IAM::s3ListMultipartUploadParts))
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWListMultipart::execute()
+void RGWListMultipart::execute(optional_yield y)
 {
   string meta_oid;
   RGWMPObj mp;
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
                                marker, parts, NULL, &truncated);
 }
 
-int RGWListBucketMultiparts::verify_permission()
+int RGWListBucketMultiparts::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this,
                                 s,
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWListBucketMultiparts::execute()
+void RGWListBucketMultiparts::execute(optional_yield y)
 {
   vector<rgw_bucket_dir_entry> objs;
   string marker_meta;
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
   }
 }
 
-void RGWGetHealthCheck::execute()
+void RGWGetHealthCheck::execute(optional_yield y)
 {
   if (!g_conf()->rgw_healthcheck_disabling_path.empty() &&
       (::access(g_conf()->rgw_healthcheck_disabling_path.c_str(), F_OK) == 0)) {
   }
 }
 
-int RGWDeleteMultiObj::verify_permission()
+int RGWDeleteMultiObj::verify_permission(optional_yield y)
 {
   if (s->iam_policy || ! s->iam_user_policies.empty()) {
     auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env,
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWDeleteMultiObj::execute()
+void RGWDeleteMultiObj::execute(optional_yield y)
 {
   RGWMultiDelDelete *multi_delete;
   vector<rgw_obj_key>::iterator iter;
   RGWObjectCtx *obj_ctx = static_cast<RGWObjectCtx *>(s->obj_ctx);
   char* buf;
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     goto error;
   }
 
 bool RGWBulkDelete::Deleter::verify_permission(RGWBucketInfo& binfo,
                                                map<string, bufferlist>& battrs,
-                                               ACLOwner& bucket_owner /* out */)
+                                               ACLOwner& bucket_owner /* out */,
+                                              optional_yield y)
 {
   RGWAccessControlPolicy bacl(store->ctx());
-  int ret = read_bucket_policy(store, s, binfo, battrs, &bacl, binfo.bucket);
+  int ret = read_bucket_policy(store, s, binfo, battrs, &bacl, binfo.bucket, y);
   if (ret < 0) {
     return false;
   }
                                  &bacl, policy, s->iam_user_policies, rgw::IAM::s3DeleteBucket);
 }
 
-bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path)
+bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path, optional_yield y)
 {
   std::unique_ptr<rgw::sal::RGWBucket> bucket;
   ACLOwner bowner;
     goto binfo_fail;
   }
 
-  if (!verify_permission(bucket->get_info(), bucket->get_attrs(), bowner)) {
+  if (!verify_permission(bucket->get_info(), bucket->get_attrs(), bowner, y)) {
     ret = -EACCES;
     goto auth_fail;
   }
     return false;
 }
 
-bool RGWBulkDelete::Deleter::delete_chunk(const std::list<acct_path_t>& paths)
+bool RGWBulkDelete::Deleter::delete_chunk(const std::list<acct_path_t>& paths, optional_yield y)
 {
   ldpp_dout(s, 20) << "in delete_chunk" << dendl;
   for (auto path : paths) {
     ldpp_dout(s, 20) << "bulk deleting path: " << path << dendl;
-    delete_single(path);
+    delete_single(path, y);
   }
 
   return true;
 }
 
-int RGWBulkDelete::verify_permission()
+int RGWBulkDelete::verify_permission(optional_yield y)
 {
   return 0;
 }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWBulkDelete::execute()
+void RGWBulkDelete::execute(optional_yield y)
 {
   deleter = std::unique_ptr<Deleter>(new Deleter(this, store, s));
 
       return;
     }
 
-    ret = deleter->delete_chunk(items);
+    ret = deleter->delete_chunk(items, y);
   } while (!op_ret && is_truncated);
 
   return;
 
 constexpr std::array<int, 2> RGWBulkUploadOp::terminal_errors;
 
-int RGWBulkUploadOp::verify_permission()
+int RGWBulkUploadOp::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return std::make_pair(bucket_path, file_prefix);
 }
 
-int RGWBulkUploadOp::handle_dir_verify_permission()
+int RGWBulkUploadOp::handle_dir_verify_permission(optional_yield y)
 {
   if (s->user->get_max_buckets() > 0) {
     rgw::sal::RGWBucketList buckets;
     std::string marker;
     op_ret = rgw_read_user_buckets(store, s->user->get_user(), buckets,
                                    marker, std::string(), s->user->get_max_buckets(),
-                                   false, null_yield);
+                                   false, y);
     if (op_ret < 0) {
       return op_ret;
     }
   dir_ctx.emplace(store->svc()->sysobj->init_obj_ctx());
 }
 
-int RGWBulkUploadOp::handle_dir(const std::string_view path)
+int RGWBulkUploadOp::handle_dir(const std::string_view path, optional_yield y)
 {
   ldpp_dout(this, 20) << "got directory=" << path << dendl;
 
-  op_ret = handle_dir_verify_permission();
+  op_ret = handle_dir_verify_permission(y);
   if (op_ret < 0) {
     return op_ret;
   }
                                 pquota_info, policy, attrs,
                                 out_info, ep_objv,
                                 true, false, &bucket_exists,
-                               info, &bucket, null_yield);
+                               info, &bucket, y);
   /* continue if EEXIST and create_bucket will fail below.  this way we can
    * recover from a partial create by retrying it. */
   ldpp_dout(this, 20) << "rgw_create_bucket returned ret=" << op_ret
 bool RGWBulkUploadOp::handle_file_verify_permission(RGWBucketInfo& binfo,
                                                    const rgw_obj& obj,
                                                     std::map<std::string, ceph::bufferlist>& battrs,
-                                                    ACLOwner& bucket_owner /* out */)
+                                                    ACLOwner& bucket_owner /* out */,
+                                                   optional_yield y)
 {
   RGWAccessControlPolicy bacl(store->ctx());
-  op_ret = read_bucket_policy(store, s, binfo, battrs, &bacl, binfo.bucket);
+  op_ret = read_bucket_policy(store, s, binfo, battrs, &bacl, binfo.bucket, y);
   if (op_ret < 0) {
     ldpp_dout(this, 20) << "cannot read_policy() for bucket" << dendl;
     return false;
 
 int RGWBulkUploadOp::handle_file(const std::string_view path,
                                  const size_t size,
-                                 AlignedStreamGetter& body)
+                                 AlignedStreamGetter& body, optional_yield y)
 {
 
   ldpp_dout(this, 20) << "got file=" << path << ", size=" << size << dendl;
 
   if (! handle_file_verify_permission(bucket->get_info(),
                                      obj->get_obj(),
-                                     bucket->get_attrs(), bowner)) {
+                                     bucket->get_attrs(), bowner, y)) {
     ldpp_dout(this, 20) << "object creation unauthorized" << dendl;
     op_ret = -EACCES;
     return op_ret;
   }
 
-  op_ret = bucket->check_quota(user_quota, bucket_quota, size, null_yield);
+  op_ret = bucket->check_quota(user_quota, bucket_quota, size, y);
   if (op_ret < 0) {
     return op_ret;
   }
     return op_ret;
   }
 
-  op_ret = bucket->check_quota(user_quota, bucket_quota, size, null_yield);
+  op_ret = bucket->check_quota(user_quota, bucket_quota, size, y);
   if (op_ret < 0) {
     ldpp_dout(this, 20) << "quota exceeded for path=" << path << dendl;
     return op_ret;
   return op_ret;
 }
 
-void RGWBulkUploadOp::execute()
+void RGWBulkUploadOp::execute(optional_yield y)
 {
   ceph::bufferlist buffer(64 * 1024);
 
                                           rgw::tar::BLOCK_SIZE, *stream);
           op_ret = handle_file(filename,
                                header->get_filesize(),
-                               body);
+                               body, y);
           if (! op_ret) {
             /* Only regular files counts. */
             num_created++;
           ldpp_dout(this, 2) << "handling regular directory" << dendl;
 
           std::string_view dirname = bucket_path.empty() ? header->get_filename() : bucket_path;
-          op_ret = handle_dir(dirname);
+          op_ret = handle_dir(dirname, y);
           if (op_ret < 0 && op_ret != -ERR_BUCKET_EXISTS) {
             failures.emplace_back(op_ret, std::string(dirname));
           }
   return len;
 }
 
-int RGWSetAttrs::verify_permission()
+int RGWSetAttrs::verify_permission(optional_yield y)
 {
   // This looks to be part of the RGW-NFS machinery and has no S3 or
   // Swift equivalent.
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWSetAttrs::execute()
+void RGWSetAttrs::execute(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetObjLayout::execute()
+void RGWGetObjLayout::execute(optional_yield y)
 {
   /* Make sure bucket is correct */
   s->object->set_bucket(s->bucket.get());
 }
 
 
-int RGWConfigBucketMetaSearch::verify_permission()
+int RGWConfigBucketMetaSearch::verify_permission(optional_yield y)
 {
   if (!s->auth.identity->is_owner_of(s->bucket_owner.get_id())) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWConfigBucketMetaSearch::execute()
+void RGWConfigBucketMetaSearch::execute(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     ldpp_dout(this, 20) << "NOTICE: get_params() returned ret=" << op_ret << dendl;
     return;
   s->bucket_attrs = s->bucket->get_attrs();
 }
 
-int RGWGetBucketMetaSearch::verify_permission()
+int RGWGetBucketMetaSearch::verify_permission(optional_yield y)
 {
   if (!s->auth.identity->is_owner_of(s->bucket_owner.get_id())) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-int RGWDelBucketMetaSearch::verify_permission()
+int RGWDelBucketMetaSearch::verify_permission(optional_yield y)
 {
   if (!s->auth.identity->is_owner_of(s->bucket_owner.get_id())) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWDelBucketMetaSearch::execute()
+void RGWDelBucketMetaSearch::execute(optional_yield y)
 {
   s->bucket->get_info().mdsearch_config.clear();
 
   return 0;
 }
 
-int RGWHandler::do_init_permissions()
+int RGWHandler::do_init_permissions(optional_yield y)
 {
-  int ret = rgw_build_bucket_policies(store, s);
+  int ret = rgw_build_bucket_policies(store, s, y);
   if (ret < 0) {
     ldpp_dout(s, 10) << "init_permissions on " << s->bucket
         << " failed, ret=" << ret << dendl;
   return ret;
 }
 
-int RGWHandler::do_read_permissions(RGWOp *op, bool only_bucket)
+int RGWHandler::do_read_permissions(RGWOp *op, bool only_bucket, optional_yield y)
 {
   if (only_bucket) {
     /* already read bucket info */
     return 0;
   }
-  int ret = rgw_build_object_policies(store, s, op->prefetch_data());
+  int ret = rgw_build_object_policies(store, s, op->prefetch_data(), y);
 
   if (ret < 0) {
     ldpp_dout(op, 10) << "read_permissions on " << s->bucket << ":"
   return ret;
 }
 
-int RGWOp::error_handler(int err_no, string *error_content) {
-  return dialect_handler->error_handler(err_no, error_content);
+int RGWOp::error_handler(int err_no, string *error_content, optional_yield y) {
+  return dialect_handler->error_handler(err_no, error_content, y);
 }
 
-int RGWHandler::error_handler(int err_no, string *error_content) {
+int RGWHandler::error_handler(int err_no, string *error_content, optional_yield) {
   // This is the do-nothing error handler
   return err_no;
 }
   end_header(s);
 }
 
-int RGWPutBucketPolicy::verify_permission()
+int RGWPutBucketPolicy::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketPolicy)) {
     return -EACCES;
   return 0;
 }
 
-int RGWPutBucketPolicy::get_params()
+int RGWPutBucketPolicy::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
   // At some point when I have more time I want to make a version of
   return op_ret;
 }
 
-void RGWPutBucketPolicy::execute()
+void RGWPutBucketPolicy::execute(optional_yield y)
 {
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     return;
   }
   dump_body(s, policy);
 }
 
-int RGWGetBucketPolicy::verify_permission()
+int RGWGetBucketPolicy::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicy)) {
     return -EACCES;
   return 0;
 }
 
-void RGWGetBucketPolicy::execute()
+void RGWGetBucketPolicy::execute(optional_yield y)
 {
   rgw::sal::RGWAttrs attrs(s->bucket_attrs);
   auto aiter = attrs.find(RGW_ATTR_IAM_POLICY);
   end_header(s);
 }
 
-int RGWDeleteBucketPolicy::verify_permission()
+int RGWDeleteBucketPolicy::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3DeleteBucketPolicy)) {
     return -EACCES;
   return 0;
 }
 
-void RGWDeleteBucketPolicy::execute()
+void RGWDeleteBucketPolicy::execute(optional_yield y)
 {
   op_ret = retry_raced_bucket_write(s->bucket.get(), [this] {
       rgw::sal::RGWAttrs attrs(s->bucket_attrs);
   rgw_bucket_object_pre_exec(s);
 }
 
-int RGWPutBucketObjectLock::verify_permission()
+int RGWPutBucketObjectLock::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketObjectLockConfiguration);
 }
 
-void RGWPutBucketObjectLock::execute()
+void RGWPutBucketObjectLock::execute(optional_yield y)
 {
   if (!s->bucket->get_info().obj_lock_enabled()) {
     ldpp_dout(this, 0) << "ERROR: object Lock configuration cannot be enabled on existing buckets" << dendl;
     op_ret = -EINVAL;
     return;
   }
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0) {
     return;
   }
   rgw_bucket_object_pre_exec(s);
 }
 
-int RGWGetBucketObjectLock::verify_permission()
+int RGWGetBucketObjectLock::verify_permission(optional_yield y)
 {
   return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketObjectLockConfiguration);
 }
 
-void RGWGetBucketObjectLock::execute()
+void RGWGetBucketObjectLock::execute(optional_yield y)
 {
   if (!s->bucket->get_info().obj_lock_enabled()) {
     op_ret = -ERR_NO_SUCH_OBJECT_LOCK_CONFIGURATION;
   }
 }
 
-int RGWPutObjRetention::verify_permission()
+int RGWPutObjRetention::verify_permission(optional_yield y)
 {
   if (!verify_object_permission(this, s, rgw::IAM::s3PutObjectRetention)) {
     return -EACCES;
   }
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret) {
     return op_ret;
   }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWPutObjRetention::execute()
+void RGWPutObjRetention::execute(optional_yield y)
 {
   if (!s->bucket->get_info().obj_lock_enabled()) {
     ldpp_dout(this, 0) << "ERROR: object retention can't be set if bucket object lock not configured" << dendl;
   return;
 }
 
-int RGWGetObjRetention::verify_permission()
+int RGWGetObjRetention::verify_permission(optional_yield y)
 {
   if (!verify_object_permission(this, s, rgw::IAM::s3GetObjectRetention)) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetObjRetention::execute()
+void RGWGetObjRetention::execute(optional_yield y)
 {
   if (!s->bucket->get_info().obj_lock_enabled()) {
     ldpp_dout(this, 0) << "ERROR: bucket object lock not configured" << dendl;
   return;
 }
 
-int RGWPutObjLegalHold::verify_permission()
+int RGWPutObjLegalHold::verify_permission(optional_yield y)
 {
   if (!verify_object_permission(this, s, rgw::IAM::s3PutObjectLegalHold)) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWPutObjLegalHold::execute() {
+void RGWPutObjLegalHold::execute(optional_yield y) {
   if (!s->bucket->get_info().obj_lock_enabled()) {
     ldpp_dout(this, 0) << "ERROR: object legal hold can't be set if bucket object lock not configured" << dendl;
     op_ret = -ERR_INVALID_REQUEST;
     return;
   }
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
   return;
 }
 
-int RGWGetObjLegalHold::verify_permission()
+int RGWGetObjLegalHold::verify_permission(optional_yield y)
 {
   if (!verify_object_permission(this, s, rgw::IAM::s3GetObjectLegalHold)) {
     return -EACCES;
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWGetObjLegalHold::execute()
+void RGWGetObjLegalHold::execute(optional_yield y)
 {
   if (!s->bucket->get_info().obj_lock_enabled()) {
     ldpp_dout(this, 0) << "ERROR: bucket object lock not configured" << dendl;
   return;
 }
 
-void RGWGetClusterStat::execute()
+void RGWGetClusterStat::execute(optional_yield y)
 {
   op_ret = this->store->getRados()->get_rados_handle()->cluster_stat(stats_op);
 }
 
 
-int RGWGetBucketPolicyStatus::verify_permission()
+int RGWGetBucketPolicyStatus::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicyStatus)) {
     return -EACCES;
   return 0;
 }
 
-void RGWGetBucketPolicyStatus::execute()
+void RGWGetBucketPolicyStatus::execute(optional_yield y)
 {
   isPublic = (s->iam_policy && rgw::IAM::is_public(*s->iam_policy)) || s->bucket_acl->is_public();
 }
 
-int RGWPutBucketPublicAccessBlock::verify_permission()
+int RGWPutBucketPublicAccessBlock::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketPublicAccessBlock)) {
     return -EACCES;
   return 0;
 }
 
-int RGWPutBucketPublicAccessBlock::get_params()
+int RGWPutBucketPublicAccessBlock::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
   std::tie(op_ret, data) = rgw_rest_read_all_input(s, max_size, false);
   return op_ret;
 }
 
-void RGWPutBucketPublicAccessBlock::execute()
+void RGWPutBucketPublicAccessBlock::execute(optional_yield y)
 {
   RGWXMLDecoder::XMLParser parser;
   if (!parser.init()) {
     return;
   }
 
-  op_ret = get_params();
+  op_ret = get_params(y);
   if (op_ret < 0)
     return;
 
 
 }
 
-int RGWGetBucketPublicAccessBlock::verify_permission()
+int RGWGetBucketPublicAccessBlock::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicy)) {
     return -EACCES;
   return 0;
 }
 
-void RGWGetBucketPublicAccessBlock::execute()
+void RGWGetBucketPublicAccessBlock::execute(optional_yield y)
 {
   auto attrs = s->bucket_attrs;
   if (auto aiter = attrs.find(RGW_ATTR_PUBLIC_ACCESS);
   end_header(s);
 }
 
-int RGWDeleteBucketPublicAccessBlock::verify_permission()
+int RGWDeleteBucketPublicAccessBlock::verify_permission(optional_yield y)
 {
   if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketPublicAccessBlock)) {
     return -EACCES;
   return 0;
 }
 
-void RGWDeleteBucketPublicAccessBlock::execute()
+void RGWDeleteBucketPublicAccessBlock::execute(optional_yield y)
 {
   op_ret = retry_raced_bucket_write(s->bucket.get(), [this] {
       rgw::sal::RGWAttrs attrs(s->bucket_attrs);
 
                                       rgw::sal::RGWStore *store,
                                        RGWBucketInfo& bucket_info,
                                        map<string, bufferlist>& bucket_attrs,
-                                       RGWAccessControlPolicy *policy);
+                                       RGWAccessControlPolicy *policy,
+                                      optional_yield y);
 
 class RGWHandler {
 protected:
   rgw::sal::RGWRadosStore* store{nullptr};
   struct req_state *s{nullptr};
 
-  int do_init_permissions();
-  int do_read_permissions(RGWOp* op, bool only_bucket);
+  int do_init_permissions(optional_yield y);
+  int do_read_permissions(RGWOp* op, bool only_bucket, optional_yield y);
 
 public:
   RGWHandler() {}
                    struct req_state* _s,
                    rgw::io::BasicClient* cio);
 
-  virtual int init_permissions(RGWOp*) {
+  virtual int init_permissions(RGWOp*, optional_yield y) {
     return 0;
   }
 
     return 0;
   }
 
-  virtual int read_permissions(RGWOp* op) = 0;
-  virtual int authorize(const DoutPrefixProvider* dpp) = 0;
-  virtual int postauth_init() = 0;
-  virtual int error_handler(int err_no, std::string* error_content);
+  virtual int read_permissions(RGWOp* op, optional_yield y) = 0;
+  virtual int authorize(const DoutPrefixProvider* dpp, optional_yield y) = 0;
+  virtual int postauth_init(optional_yield y) = 0;
+  virtual int error_handler(int err_no, std::string* error_content, optional_yield y);
   virtual void dump(const string& code, const string& message) const {}
 
   virtual bool supports_quota() {
 
   int get_ret() const { return op_ret; }
 
-  virtual int init_processing() {
+  virtual int init_processing(optional_yield y) {
     if (dialect_handler->supports_quota()) {
       op_ret = init_quota();
       if (op_ret < 0)
    * authentication. The alternative is to duplicate parts of the method-
    * dispatch logic in RGWHandler::authorize() and pollute it with a lot
    * of special cases. */
-  virtual int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) {
+  virtual int verify_requester(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y) {
     /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
-    return dialect_handler->authorize(this);
+    return dialect_handler->authorize(this, y);
   }
-  virtual int verify_permission() = 0;
+  virtual int verify_permission(optional_yield y) = 0;
   virtual int verify_op_mask();
   virtual void pre_exec() {}
-  virtual void execute() = 0;
+  virtual void execute(optional_yield y) = 0;
   virtual void send_response() {}
   virtual void complete() {
     send_response();
 
   virtual uint32_t op_mask() { return 0; }
 
-  virtual int error_handler(int err_no, string *error_content);
+  virtual int error_handler(int err_no, string *error_content, optional_yield y);
 
   // implements DoutPrefixProvider
   std::ostream& gen_prefix(std::ostream& out) const override;
     this->get_data = get_data;
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
   int parse_range();
   int read_user_manifest_part(
     rgw::sal::RGWBucket* bucket,
     const off_t start_ofs,
     const off_t end_ofs,
     bool swift_slo);
-  int handle_user_manifest(const char *prefix);
-  int handle_slo_manifest(bufferlist& bl);
+  int handle_user_manifest(const char *prefix, optional_yield y);
+  int handle_slo_manifest(bufferlist& bl, optional_yield y);
 
   int get_data_cb(bufferlist& bl, off_t ofs, off_t len);
 
-  virtual int get_params() = 0;
-  virtual int send_response_data_error() = 0;
+  virtual int get_params(optional_yield y) = 0;
+  virtual int send_response_data_error(optional_yield y) = 0;
   virtual int send_response_data(bufferlist& bl, off_t ofs, off_t len) = 0;
 
   const char* name() const override { return "get_obj"; }
   bufferlist tags_bl;
   bool has_tags{false};
  public:
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   void pre_exec() override;
 
   virtual void send_response_data(bufferlist& bl) = 0;
  protected:
   bufferlist tags_bl;
  public:
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   virtual void send_response() override = 0;
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   const char* name() const override { return "put_obj_tags"; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
   RGWOpType get_type() override { return RGW_OP_PUT_OBJ_TAGGING; }
 class RGWDeleteObjTags: public RGWOp {
  public:
   void pre_exec() override;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "delete_obj_tags"; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
   bufferlist tags_bl;
   bool has_tags{false};
 public:
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   void pre_exec() override;
 
   virtual void send_response_data(bufferlist& bl) = 0;
   bufferlist tags_bl;
   bufferlist in_data;
 public:
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   virtual void send_response() override = 0;
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   const char* name() const override { return "put_bucket_tags"; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
   RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_TAGGING; }
 class RGWDeleteBucketTags : public RGWOp {
 public:
   void pre_exec() override;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "delete_bucket_tags"; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
 
 class RGWGetBucketReplication : public RGWOp {
 public:
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   void pre_exec() override;
 
   virtual void send_response_data() = 0;
   bufferlist in_data;
   std::vector<rgw_sync_policy_group> sync_policy_groups;
 public:
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   virtual void send_response() override = 0;
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   const char* name() const override { return "put_bucket_replication"; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
   RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_REPLICATION; }
   virtual void update_sync_policy(rgw_sync_policy_info *policy) = 0;
 public:
   void pre_exec() override;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "delete_bucket_replication"; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_DELETE; }
 
     bool verify_permission(RGWBucketInfo& binfo,
                            map<string, bufferlist>& battrs,
-                           ACLOwner& bucket_owner /* out */);
-    bool delete_single(const acct_path_t& path);
-    bool delete_chunk(const std::list<acct_path_t>& paths);
+                           ACLOwner& bucket_owner /* out */,
+                          optional_yield y);
+    bool delete_single(const acct_path_t& path, optional_yield y);
+    bool delete_chunk(const std::list<acct_path_t>& paths, optional_yield y);
   };
   /* End of Deleter subclass */
 
     : deleter(nullptr) {
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   virtual int get_data(std::list<acct_path_t>& items,
                        bool * is_truncated) = 0;
   bool handle_file_verify_permission(RGWBucketInfo& binfo,
                                     const rgw_obj& obj,
                                     std::map<std::string, ceph::bufferlist>& battrs,
-                                     ACLOwner& bucket_owner /* out */);
+                                     ACLOwner& bucket_owner /* out */,
+                                    optional_yield y);
   int handle_file(std::string_view path,
                   size_t size,
-                  AlignedStreamGetter& body);
+                  AlignedStreamGetter& body,
+                 optional_yield y);
 
-  int handle_dir_verify_permission();
-  int handle_dir(std::string_view path);
+  int handle_dir_verify_permission(optional_yield y);
+  int handle_dir(std::string_view path, optional_yield y);
 
 public:
   RGWBulkUploadOp()
             struct req_state* const s,
             RGWHandler* const h) override;
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "bulk_upload"; }
 
       is_truncated(false) {
   }
 
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   virtual void handle_listing_chunk(rgw::sal::RGWBucketList&& buckets) {
     /* The default implementation, used by e.g. S3, just generates a new
      * part of listing and sends it client immediately. Swift can behave
   RGWGetUsage() : sent_data(false), show_log_entries(true), show_log_sum(true){
   }
 
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override {}
 
   virtual bool should_get_stats() { return false; }
 public:
   RGWStatAccount() = default;
 
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "stat_account"; }
   RGWListBucket() : list_versions(false), max(0),
                     default_max(0), is_truncated(false),
                    allow_unordered(false), shard_id(-1) {}
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
     RGWOp::init(store, s, h);
   }
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "list_bucket"; }
   RGWOpType get_type() override { return RGW_OP_LIST_BUCKET; }
 class RGWGetBucketLogging : public RGWOp {
 public:
   RGWGetBucketLogging() {}
-  int verify_permission() override;
-  void execute() override { }
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield) override { }
 
   void send_response() override = 0;
   const char* name() const override { return "get_bucket_logging"; }
 public:
   RGWGetBucketLocation() {}
   ~RGWGetBucketLocation() override {}
-  int verify_permission() override;
-  void execute() override { }
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield) override { }
 
   void send_response() override = 0;
   const char* name() const override { return "get_bucket_location"; }
 public:
   RGWGetBucketVersioning() = default;
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "get_bucket_versioning"; }
 public:
   RGWSetBucketVersioning() : versioning_status(VersioningNotChanged) {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() { return 0; }
+  virtual int get_params(optional_yield y) { return 0; }
 
   void send_response() override = 0;
   const char* name() const override { return "set_bucket_versioning"; }
 public:
   RGWGetBucketWebsite() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "get_bucket_website"; }
 public:
   RGWSetBucketWebsite() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() { return 0; }
+  virtual int get_params(optional_yield y) { return 0; }
 
   void send_response() override = 0;
   const char* name() const override { return "set_bucket_website"; }
 public:
   RGWDeleteBucketWebsite() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "delete_bucket_website"; }
   std::unique_ptr<rgw::sal::RGWBucket> bucket;
 
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "stat_bucket"; }
     attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
   void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
     RGWOp::init(store, s, h);
     policy.set_ctx(s->cct);
     relaxed_region_enforcement =
        s->cct->_conf.get_val<bool>("rgw_relaxed_region_enforcement");
   }
-  virtual int get_params() { return 0; }
+  virtual int get_params(optional_yield y) { return 0; }
   void send_response() override = 0;
   const char* name() const override { return "create_bucket"; }
   RGWOpType get_type() override { return RGW_OP_CREATE_BUCKET; }
 public:
   RGWDeleteBucket() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "delete_bucket"; }
     policy.set_ctx(s->cct);
   }
 
-  virtual int init_processing() override;
+  virtual int init_processing(optional_yield y) override;
 
   void emplace_attr(std::string&& key, buffer::list&& bl) {
     attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   /* this is for cases when copying data from other object */
   virtual int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
   int get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len);
   int get_data(const off_t fst, const off_t lst, bufferlist& bl);
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   virtual int get_data(bufferlist& bl) = 0;
   void send_response() override = 0;
   const char* name() const override { return "put_obj"; }
     policy.set_ctx(s->cct);
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   virtual int get_encrypt_filter(std::unique_ptr<rgw::putobj::DataProcessor> *filter,
                                  rgw::putobj::DataProcessor *cb) {
     return 0;
   }
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   virtual int get_data(ceph::bufferlist& bl, bool& again) = 0;
   void send_response() override = 0;
   const char* name() const override { return "post_obj"; }
     RGWOp::init(store, s, h);
     policy.set_ctx(s->cct);
   }
-  int init_processing() override;
-  int verify_permission() override;
+  int init_processing(optional_yield y) override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override { }
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   virtual void filter_out_temp_url(map<string, bufferlist>& add_attrs,
                                    const set<string>& rmattr_names,
     policy.set_ctx(s->cct);
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "put_bucket_metadata"; }
   RGWOpType get_type() override { return RGW_OP_PUT_METADATA_BUCKET; }
     RGWOp::init(store, s, h);
     policy.set_ctx(s->cct);
   }
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "put_obj_metadata"; }
   RGWOpType get_type() override { return RGW_OP_PUT_METADATA_OBJECT; }
       bypass_governance_mode(false) {
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
-  int handle_slo_manifest(bufferlist& bl);
+  void execute(optional_yield y) override;
+  int handle_slo_manifest(bufferlist& bl, optional_yield y);
 
-  virtual int get_params() { return 0; }
+  virtual int get_params(optional_yield y) { return 0; }
   void send_response() override = 0;
   const char* name() const override { return "delete_obj"; }
   RGWOpType get_type() override { return RGW_OP_DELETE_OBJ; }
     RGWOp::init(store, s, h);
     dest_policy.set_ctx(s->cct);
   }
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
   void progress_cb(off_t ofs);
 
   virtual int check_storage_class(const rgw_placement_rule& src_placement) {
   }
 
   virtual int init_dest_policy() { return 0; }
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   virtual void send_partial_response(off_t ofs) {}
   void send_response() override = 0;
   const char* name() const override { return "copy_obj"; }
 public:
   RGWGetACLs() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "get_acls"; }
   RGWPutACLs() {}
   ~RGWPutACLs() override {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   virtual int get_policy_from_state(rgw::sal::RGWRadosStore *store, struct req_state *s, stringstream& ss) { return 0; }
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "put_acls"; }
   RGWOpType get_type() override { return RGW_OP_PUT_ACLS; }
   RGWGetLC() { }
   ~RGWGetLC() override { }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override = 0;
+  void execute(optional_yield) override = 0;
 
   void send_response() override = 0;
   const char* name() const override { return "get_lifecycle"; }
     cookie = buf;
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
 //  virtual int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) { return 0; }
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "put_lifecycle"; }
   RGWOpType get_type() override { return RGW_OP_PUT_LC; }
 class RGWDeleteLC : public RGWOp {
 public:
   RGWDeleteLC() = default;
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "delete_lifecycle"; }
 public:
   RGWGetCORS() {}
 
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "get_cors"; }
   RGWPutCORS() {}
   ~RGWPutCORS() override {}
 
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "put_cors"; }
   RGWOpType get_type() override { return RGW_OP_PUT_CORS; }
 public:
   RGWDeleteCORS() {}
 
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "delete_cors"; }
                      req_hdrs(NULL), req_meth(NULL) {
   }
 
-  int verify_permission() override {return 0;}
+  int verify_permission(optional_yield y) override {return 0;}
   int validate_cors_request(RGWCORSConfiguration *cc);
-  void execute() override;
+  void execute(optional_yield y) override;
   void get_response_params(string& allowed_hdrs, string& exp_hdrs, unsigned *max_age);
   void send_response() override = 0;
   const char* name() const override { return "options_cors"; }
 public:
   RGWGetRequestPayment() : requester_pays(0) {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "get_request_payment"; }
 public:
  RGWSetRequestPayment() : requester_pays(false) {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() { return 0; }
+  virtual int get_params(optional_yield y) { return 0; }
 
   void send_response() override = 0;
   const char* name() const override { return "set_request_payment"; }
     RGWOp::init(store, s, h);
     policy.set_ctx(s->cct);
   }
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "init_multipart"; }
   RGWOpType get_type() override { return RGW_OP_INIT_MULTIPART; }
     MPSerializer() : lock("RGWCompleteMultipart"), locked(false)
       {}
 
-    int try_lock(const std::string& oid, utime_t dur);
+    int try_lock(const std::string& oid, utime_t dur, optional_yield y);
 
     int unlock() {
       return lock.unlock(&ioctx, oid);
   RGWCompleteMultipart() {}
   ~RGWCompleteMultipart() override {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
   void complete() override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "complete_multipart"; }
   RGWOpType get_type() override { return RGW_OP_COMPLETE_MULTIPART; }
 public:
   RGWAbortMultipart() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   void send_response() override = 0;
   const char* name() const override { return "abort_multipart"; }
     RGWOp::init(store, s, h);
     policy = RGWAccessControlPolicy(s->cct);
   }
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "list_multipart"; }
   RGWOpType get_type() override { return RGW_OP_LIST_MULTIPART; }
     max_uploads = default_max;
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "list_bucket_multiparts"; }
   RGWOpType get_type() override { return RGW_OP_LIST_BUCKET_MULTIPARTS; }
   RGWGetCrossDomainPolicy() = default;
   ~RGWGetCrossDomainPolicy() override = default;
 
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
 
-  void execute() override {
+  void execute(optional_yield) override {
     op_ret = 0;
   }
 
   RGWGetHealthCheck() = default;
   ~RGWGetHealthCheck() override = default;
 
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "get_health_check"; }
 
     quiet = false;
     status_dumped = false;
   }
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   virtual void send_status() = 0;
   virtual void begin_response() = 0;
   virtual void send_partial_response(rgw_obj_key& key, bool delete_marker,
   RGWInfo() = default;
   ~RGWInfo() override = default;
 
-  int verify_permission() override { return 0; }
+  int verify_permission(optional_yield) override { return 0; }
   const char* name() const override { return "get info"; }
   RGWOpType get_type() override { return RGW_OP_GET_INFO; }
   uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
 };
 
-extern int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s);
+extern int rgw_build_bucket_policies(rgw::sal::RGWRadosStore* store, struct req_state* s, optional_yield y);
 extern int rgw_build_object_policies(rgw::sal::RGWRadosStore *store, struct req_state *s,
-                                    bool prefetch_data);
+                                    bool prefetch_data, optional_yield y);
 extern void rgw_build_iam_environment(rgw::sal::RGWRadosStore* store,
                                                                          struct req_state* s);
 extern vector<rgw::IAM::Policy> get_iam_user_policy_from_attr(CephContext* cct,
                         map<string, bufferlist>& attrs,
                         const string& tenant);
 
-static inline int get_system_versioning_params(req_state *s,
-                                             uint64_t *olh_epoch,
-                                             string *version_id)
+inline int get_system_versioning_params(req_state *s,
+                                       uint64_t *olh_epoch,
+                                       string *version_id)
 {
   if (!s->system_request) {
     return 0;
  * On failure returns a negative error code.
  *
  */
-static inline int rgw_get_request_metadata(CephContext* const cct,
-                                           struct req_info& info,
-                                           std::map<std::string, ceph::bufferlist>& attrs,
-                                           const bool allow_empty_attrs = true)
+inline int rgw_get_request_metadata(CephContext* const cct,
+                                   struct req_info& info,
+                                   std::map<std::string, ceph::bufferlist>& attrs,
+                                   const bool allow_empty_attrs = true)
 {
   static const std::set<std::string> blocklisted_headers = {
       "x-amz-server-side-encryption-customer-algorithm",
   return 0;
 } /* rgw_get_request_metadata */
 
-static inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,
-                                       map<string, bufferlist>& attrs)
+inline void encode_delete_at_attr(boost::optional<ceph::real_time> delete_at,
+                                 map<string, bufferlist>& attrs)
 {
   if (delete_at == boost::none) {
     return;
   attrs[RGW_ATTR_DELETE_AT] = delatbl;
 } /* encode_delete_at_attr */
 
-static inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map<string, bufferlist>& attrs)
+inline void encode_obj_tags_attr(RGWObjTags* obj_tags, map<string, bufferlist>& attrs)
 {
   if (obj_tags == nullptr){
     // we assume the user submitted a tag format which we couldn't parse since
   attrs[RGW_ATTR_TAGS] = tagsbl;
 }
 
-static inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
-                                         map<string, bufferlist>& attrs)
+inline int encode_dlo_manifest_attr(const char * const dlo_manifest,
+                                   map<string, bufferlist>& attrs)
 {
   string dm = dlo_manifest;
 
   return 0;
 } /* encode_dlo_manifest_attr */
 
-static inline void complete_etag(MD5& hash, string *etag)
+inline void complete_etag(MD5& hash, string *etag)
 {
   char etag_buf[CEPH_CRYPTO_MD5_DIGESTSIZE];
   char etag_buf_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 16];
     attrs.emplace(std::move(key), std::move(bl));
   }
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   void send_response() override = 0;
   const char* name() const override { return "set_attrs"; }
   RGWOpType get_type() override { return RGW_OP_SET_ATTRS; }
   int check_caps(RGWUserCaps& caps) {
     return caps.check_cap("admin", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_info().caps);
   }
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "get_obj_layout"; }
   virtual RGWOpType get_type() override { return RGW_OP_GET_OBJ_LAYOUT; }
   ~RGWPutBucketPolicy() {
   }
   void send_response() override;
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   uint32_t op_mask() override {
     return RGW_OP_TYPE_WRITE;
   }
-  void execute() override;
-  int get_params();
+  void execute(optional_yield y) override;
+  int get_params(optional_yield y);
   const char* name() const override { return "put_bucket_policy"; }
   RGWOpType get_type() override {
     return RGW_OP_PUT_BUCKET_POLICY;
 public:
   RGWGetBucketPolicy() = default;
   void send_response() override;
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   uint32_t op_mask() override {
     return RGW_OP_TYPE_READ;
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "get_bucket_policy"; }
   RGWOpType get_type() override {
     return RGW_OP_GET_BUCKET_POLICY;
 public:
   RGWDeleteBucketPolicy() = default;
   void send_response() override;
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   uint32_t op_mask() override {
     return RGW_OP_TYPE_WRITE;
   }
-  void execute() override;
-  int get_params();
+  void execute(optional_yield y) override;
+  int get_params(optional_yield y);
   const char* name() const override { return "delete_bucket_policy"; }
   RGWOpType get_type() override {
     return RGW_OP_DELETE_BUCKET_POLICY;
 public:
   RGWPutBucketObjectLock() = default;
   ~RGWPutBucketObjectLock() {}
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
-  virtual void send_response() = 0;
-  virtual int get_params() = 0;
+  void execute(optional_yield y) override;
+  virtual void send_response() override = 0;
+  virtual int get_params(optional_yield y) = 0;
   const char* name() const override { return "put_bucket_object_lock"; }
   RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_OBJ_LOCK; }
   uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
 
 class RGWGetBucketObjectLock : public RGWOp {
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
-  virtual void send_response() = 0;
+  void execute(optional_yield y) override;
+  virtual void send_response() override = 0;
   const char* name() const override {return "get_bucket_object_lock"; }
   RGWOpType get_type() override { return RGW_OP_GET_BUCKET_OBJ_LOCK; }
   uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
   bool bypass_governance_mode;
 public:
   RGWPutObjRetention():bypass_perm(true), bypass_governance_mode(false) {}
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
   virtual void send_response() override = 0;
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   const char* name() const override { return "put_obj_retention"; }
   uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
   RGWOpType get_type() override { return RGW_OP_PUT_OBJ_RETENTION; }
 protected:
   RGWObjectRetention obj_retention;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
-  virtual void send_response() = 0;
+  void execute(optional_yield y) override;
+  virtual void send_response() override = 0;
   const char* name() const override {return "get_obj_retention"; }
   RGWOpType get_type() override { return RGW_OP_GET_OBJ_RETENTION; }
   uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
   bufferlist data;
   RGWObjectLegalHold obj_legal_hold;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
   virtual void send_response() override = 0;
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   const char* name() const override { return "put_obj_legal_hold"; }
   uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
   RGWOpType get_type() override { return RGW_OP_PUT_OBJ_LEGAL_HOLD; }
 protected:
   RGWObjectLegalHold obj_legal_hold;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
-  virtual void send_response() = 0;
+  void execute(optional_yield y) override;
+  virtual void send_response() override = 0;
   const char* name() const override {return "get_obj_legal_hold"; }
   RGWOpType get_type() override { return RGW_OP_GET_OBJ_LEGAL_HOLD; }
   uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
 public:
   RGWConfigBucketMetaSearch() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
-  virtual int get_params() = 0;
+  virtual int get_params(optional_yield y) = 0;
   const char* name() const override { return "config_bucket_meta_search"; }
   virtual RGWOpType get_type() override { return RGW_OP_CONFIG_BUCKET_META_SEARCH; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
 public:
   RGWGetBucketMetaSearch() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override {}
+  void execute(optional_yield) override {}
 
   const char* name() const override { return "get_bucket_meta_search"; }
   virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_META_SEARCH; }
 public:
   RGWDelBucketMetaSearch() {}
 
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "delete_bucket_meta_search"; }
   virtual RGWOpType delete_type() { return RGW_OP_DEL_BUCKET_META_SEARCH; }
   void init(rgw::sal::RGWRadosStore *store, struct req_state *s, RGWHandler *h) override {
     RGWOp::init(store, s, h);
   }
-  int verify_permission() override {return 0;}
+  int verify_permission(optional_yield) override {return 0;}
   virtual void send_response() override = 0;
-  virtual int get_params() = 0;
-  void execute() override;
+  virtual int get_params(optional_yield y) = 0;
+  void execute(optional_yield y) override;
   const char* name() const override { return "get_cluster_stat"; }
   dmc::client_id dmclock_client() override { return dmc::client_id::admin; }
 };
 protected:
   bool isPublic {false};
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   const char* name() const override { return "get_bucket_policy_status"; }
   virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_POLICY_STATUS; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
-  void execute() override;
+  void execute(optional_yield y) override;
   dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
 };
 
   bufferlist data;
   PublicAccessBlockConfiguration access_conf;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   const char* name() const override { return "put_bucket_public_access_block";}
   virtual RGWOpType get_type() override { return RGW_OP_PUT_BUCKET_PUBLIC_ACCESS_BLOCK; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
-  int get_params();
-  void execute() override;
+  int get_params(optional_yield y);
+  void execute(optional_yield y) override;
   dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
 };
 
 protected:
   PublicAccessBlockConfiguration access_conf;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   const char* name() const override { return "get_bucket_public_access_block";}
   virtual RGWOpType get_type() override { return RGW_OP_GET_BUCKET_PUBLIC_ACCESS_BLOCK; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
-  int get_params();
-  void execute() override;
+  int get_params(optional_yield y);
+  void execute(optional_yield y) override;
   dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
 };
 
 protected:
   PublicAccessBlockConfiguration access_conf;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   const char* name() const override { return "delete_bucket_public_access_block";}
   virtual RGWOpType get_type() override { return RGW_OP_DELETE_BUCKET_PUBLIC_ACCESS_BLOCK; }
   virtual uint32_t op_mask() override { return RGW_OP_TYPE_WRITE; }
-  int get_params();
-  void execute() override;
+  int get_params(optional_yield y);
+  void execute(optional_yield y) override;
   void send_response() override;
   dmc::client_id dmclock_client() override { return dmc::client_id::metadata; }
 };
 
-static inline int parse_value_and_bound(
+inline int parse_value_and_bound(
     const string &input,
     int &output,
     const long lower_bound,
 
                               RGWOp *& op,
                               RGWRequest * const req,
                               req_state * const s,
+                             optional_yield y,
                               const bool skip_retarget)
 {
   ldpp_dout(op, 2) << "init permissions" << dendl;
-  int ret = handler->init_permissions(op);
+  int ret = handler->init_permissions(op, y);
   if (ret < 0) {
     return ret;
   }
 
   /* If necessary extract object ACL and put them into req_state. */
   ldpp_dout(op, 2) << "reading permissions" << dendl;
-  ret = handler->read_permissions(op);
+  ret = handler->read_permissions(op, y);
   if (ret < 0) {
     return ret;
   }
 
   ldpp_dout(op, 2) << "init op" << dendl;
-  ret = op->init_processing();
+  ret = op->init_processing(y);
   if (ret < 0) {
     return ret;
   }
   }
 
   ldpp_dout(op, 2) << "verifying op permissions" << dendl;
-  ret = op->verify_permission();
+  ret = op->verify_permission(y);
   if (ret < 0) {
     if (s->system_request) {
       dout(2) << "overriding permissions due to system operation" << dendl;
   op->pre_exec();
 
   ldpp_dout(op, 2) << "executing" << dendl;
-  op->execute();
+  op->execute(y);
 
   ldpp_dout(op, 2) << "completing" << dendl;
   op->complete();
 
   if (ret < 0) {
     s->cio = client_io;
-    abort_early(s, nullptr, ret, nullptr);
+    abort_early(s, nullptr, ret, nullptr, yield);
     return ret;
   }
 
                                                client_io, &mgr, &init_error);
   rgw::dmclock::SchedulerCompleter c;
   if (init_error != 0) {
-    abort_early(s, nullptr, init_error, nullptr);
+    abort_early(s, nullptr, init_error, nullptr, yield);
     goto done;
   }
   dout(10) << "handler=" << typeid(*handler).name() << dendl;
   ldpp_dout(s, 2) << "getting op " << s->op << dendl;
   op = handler->get_op();
   if (!op) {
-    abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED, handler);
+    abort_early(s, NULL, -ERR_METHOD_NOT_ALLOWED, handler, yield);
     goto done;
   }
   {
       ret = -ERR_RATE_LIMITED;
     }
     ldpp_dout(op,0) << "Scheduling request failed with " << ret << dendl;
-    abort_early(s, op, ret, handler);
+    abort_early(s, op, ret, handler, yield);
     goto done;
   }
   req->op = op;
 
   try {
     ldpp_dout(op, 2) << "verifying requester" << dendl;
-    ret = op->verify_requester(auth_registry);
+    ret = op->verify_requester(auth_registry, yield);
     if (ret < 0) {
       dout(10) << "failed to authorize request" << dendl;
-      abort_early(s, op, ret, handler);
+      abort_early(s, op, ret, handler, yield);
       goto done;
     }
 
     }
 
     ldpp_dout(op, 2) << "normalizing buckets and tenants" << dendl;
-    ret = handler->postauth_init();
+    ret = handler->postauth_init(yield);
     if (ret < 0) {
       dout(10) << "failed to run post-auth init" << dendl;
-      abort_early(s, op, ret, handler);
+      abort_early(s, op, ret, handler, yield);
       goto done;
     }
 
     if (s->user->get_info().suspended) {
       dout(10) << "user is suspended, uid=" << s->user->get_id() << dendl;
-      abort_early(s, op, -ERR_USER_SUSPENDED, handler);
+      abort_early(s, op, -ERR_USER_SUSPENDED, handler, yield);
       goto done;
     }
 
-    ret = rgw_process_authenticated(handler, op, req, s);
+    ret = rgw_process_authenticated(handler, op, req, s, yield);
     if (ret < 0) {
-      abort_early(s, op, ret, handler);
+      abort_early(s, op, ret, handler, yield);
       goto done;
     }
   } catch (const ceph::crypto::DigestException& e) {
     dout(0) << "authentication failed" << e.what() << dendl;
-    abort_early(s, op, -ERR_INVALID_SECRET_KEY, handler);
+    abort_early(s, op, -ERR_INVALID_SECRET_KEY, handler, yield);
   }
 
 done:
 
                                      RGWOp*& op,
                                      RGWRequest* req,
                                      req_state* s,
+                                    optional_yield y,
                                      bool skip_retarget = false);
 
 #if defined(def_dout_subsys)
 
 }
 
 void abort_early(struct req_state *s, RGWOp* op, int err_no,
-               RGWHandler* handler)
+                RGWHandler* handler, optional_yield y)
 {
   string error_content("");
   if (!s->formatter) {
   // op->error_handler is responsible for calling it's handler error_handler
   if (op != NULL) {
     int new_err_no;
-    new_err_no = op->error_handler(err_no, &error_content);
+    new_err_no = op->error_handler(err_no, &error_content, y);
     ldout(s->cct, 1) << "op->ERRORHANDLER: err_no=" << err_no
                      << " new_err_no=" << new_err_no << dendl;
     err_no = new_err_no;
   } else if (handler != NULL) {
     int new_err_no;
-    new_err_no = handler->error_handler(err_no, &error_content);
+    new_err_no = handler->error_handler(err_no, &error_content, y);
     ldout(s->cct, 1) << "handler->ERRORHANDLER: err_no=" << err_no
                      << " new_err_no=" << new_err_no << dendl;
     err_no = new_err_no;
   }
 }
 
-int RGWGetObj_ObjStore::get_params()
+int RGWGetObj_ObjStore::get_params(optional_yield y)
 {
   range_str = s->info.env->get("HTTP_RANGE");
   if_mod = s->info.env->get("HTTP_IF_MODIFIED_SINCE");
   return 0;
 }
 
-int RGWPutObj_ObjStore::get_params()
+int RGWPutObj_ObjStore::get_params(optional_yield y)
 {
   /* start gettorrent */
   if (s->cct->_conf->rgw_torrent_flag)
   return 0;
 }
 
-int RGWPostObj_ObjStore::get_params()
+int RGWPostObj_ObjStore::get_params(optional_yield y)
 {
   if (s->expect_cont) {
     /* OK, here it really gets ugly. With POST, the params are embedded in the
 }
 
 
-int RGWPutACLs_ObjStore::get_params()
+int RGWPutACLs_ObjStore::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
   std::tie(op_ret, data) = rgw_rest_read_all_input(s, max_size, false);
   return op_ret;
 }
 
-int RGWPutLC_ObjStore::get_params()
+int RGWPutLC_ObjStore::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
   std::tie(op_ret, data) = rgw_rest_read_all_input(s, max_size, false);
   return op_ret;
 }
 
-int RGWPutBucketObjectLock_ObjStore::get_params()
+int RGWPutBucketObjectLock_ObjStore::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
   std::tie(op_ret, data) = rgw_rest_read_all_input(s, max_size, false);
   return op_ret;
 }
 
-int RGWPutObjLegalHold_ObjStore::get_params()
+int RGWPutObjLegalHold_ObjStore::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
   std::tie(op_ret, data) = rgw_rest_read_all_input(s, max_size, false);
   return std::make_tuple(0, std::move(bl));
 }
 
-int RGWCompleteMultipart_ObjStore::get_params()
+int RGWCompleteMultipart_ObjStore::get_params(optional_yield y)
 {
   upload_id = s->info.args.get("uploadId");
 
   return 0;
 }
 
-int RGWListMultipart_ObjStore::get_params()
+int RGWListMultipart_ObjStore::get_params(optional_yield y)
 {
   upload_id = s->info.args.get("uploadId");
 
   return op_ret;
 }
 
-int RGWListBucketMultiparts_ObjStore::get_params()
+int RGWListBucketMultiparts_ObjStore::get_params(optional_yield y)
 {
   delimiter = s->info.args.get("delimiter");
   prefix = s->info.args.get("prefix");
   return 0;
 }
 
-int RGWDeleteMultiObj_ObjStore::get_params()
+int RGWDeleteMultiObj_ObjStore::get_params(optional_yield y)
 {
 
   if (s->bucket_name.empty()) {
   flusher.flush();
 }
 
-int RGWRESTOp::verify_permission()
+int RGWRESTOp::verify_permission(optional_yield)
 {
   return check_caps(s->user->get_info().caps);
 }
   return OP_UNKNOWN;
 }
 
-int RGWHandler_REST::init_permissions(RGWOp* op)
+int RGWHandler_REST::init_permissions(RGWOp* op, optional_yield y)
 {
   if (op->get_type() == RGW_OP_CREATE_BUCKET) {
     // We don't need user policies in case of STS token returned by AssumeRole, hence the check for user type
     if (! s->user->get_id().empty() && s->auth.identity->get_identity_type() != TYPE_ROLE) {
       try {
         map<string, bufferlist> uattrs;
-        if (auto ret = store->ctl()->user->get_attrs_by_uid(s->user->get_id(), &uattrs, null_yield); ! ret) {
+        if (auto ret = store->ctl()->user->get_attrs_by_uid(s->user->get_id(), &uattrs, y); ! ret) {
           auto user_policies = get_iam_user_policy_from_attr(s->cct, store, uattrs, s->user->get_tenant());
           s->iam_user_policies.insert(s->iam_user_policies.end(),
                                       std::make_move_iterator(user_policies.begin()),
     return 0;
   }
 
-  return do_init_permissions();
+  return do_init_permissions(y);
 }
 
-int RGWHandler_REST::read_permissions(RGWOp* op_obj)
+int RGWHandler_REST::read_permissions(RGWOp* op_obj, optional_yield y)
 {
   bool only_bucket = false;
 
     return -EINVAL;
   }
 
-  return do_read_permissions(op_obj, only_bucket);
+  return do_read_permissions(op_obj, only_bucket, y);
 }
 
 void RGWRESTMgr::register_resource(string resource, RGWRESTMgr *mgr)
 
                                         const uint64_t max_len,
                                         const bool allow_chunked=true);
 
-static inline std::string_view rgw_sanitized_hdrval(ceph::buffer::list& raw)
+inline std::string_view rgw_sanitized_hdrval(ceph::buffer::list& raw)
 {
   /* std::string and thus std::string_view ARE OBLIGED to carry multiple
    * 0x00 and count them to the length of a string. We need to take that
     sent_header = false;
   }
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWGetObjTags_ObjStore : public RGWGetObjTags {
   ~RGWPutObj_ObjStore() override {}
 
   int verify_params() override;
-  int get_params() override;
+  int get_params(optional_yield y) override;
   int get_data(bufferlist& bl) override;
 };
 
 
   int read_form_part_header(struct post_form_part *part, bool& done);
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 
   static int parse_part_field(const std::string& line,
                               std::string& field_name, /* out */
   RGWPutACLs_ObjStore() {}
   ~RGWPutACLs_ObjStore() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWGetLC_ObjStore : public RGWGetLC {
   RGWPutLC_ObjStore() {}
   ~RGWPutLC_ObjStore() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWDeleteLC_ObjStore : public RGWDeleteLC {
   RGWCompleteMultipart_ObjStore() {}
   ~RGWCompleteMultipart_ObjStore() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWAbortMultipart_ObjStore : public RGWAbortMultipart {
   RGWListMultipart_ObjStore() {}
   ~RGWListMultipart_ObjStore() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWListBucketMultiparts_ObjStore : public RGWListBucketMultiparts {
   RGWListBucketMultiparts_ObjStore() {}
   ~RGWListBucketMultiparts_ObjStore() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWBulkDelete_ObjStore : public RGWBulkDelete {
   RGWDeleteMultiObj_ObjStore() {}
   ~RGWDeleteMultiObj_ObjStore() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWInfo_ObjStore : public RGWInfo {
 public:
   RGWPutBucketObjectLock_ObjStore() = default;
   ~RGWPutBucketObjectLock_ObjStore() = default;
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWGetBucketObjectLock_ObjStore : public RGWGetBucketObjectLock {
 public:
   RGWPutObjLegalHold_ObjStore() = default;
   ~RGWPutObjLegalHold_ObjStore() override = default;
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWGetObjLegalHold_ObjStore : public RGWGetObjLegalHold {
   void send_response() override;
   virtual int check_caps(const RGWUserCaps& caps)
     { return -EPERM; } /* should to be implemented! */
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   dmc::client_id dmclock_client() override { return dmc::client_id::admin; }
 };
 
   static int validate_object_name(const string& object);
   static int reallocate_formatter(struct req_state *s, int type);
 
-  int init_permissions(RGWOp* op) override;
-  int read_permissions(RGWOp* op) override;
+  int init_permissions(RGWOp* op, optional_yield y) override;
+  int read_permissions(RGWOp* op, optional_yield y) override;
 
   virtual RGWOp* get_op(void);
   virtual void put_op(RGWOp* op);
                         const utime_t& val);
 
 template <class... Args>
-static inline void dump_header_prefixed(struct req_state* s,
-                                        const std::string_view& name_prefix,
-                                        const std::string_view& name,
-                                        Args&&... args) {
+inline void dump_header_prefixed(struct req_state* s,
+                                const std::string_view& name_prefix,
+                                const std::string_view& name,
+                                Args&&... args) {
   char full_name_buf[name_prefix.size() + name.size() + 1];
   const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s",
                             static_cast<int>(name_prefix.length()),
 }
 
 template <class... Args>
-static inline void dump_header_infixed(struct req_state* s,
-                                       const std::string_view& prefix,
-                                       const std::string_view& infix,
-                                       const std::string_view& sufix,
-                                       Args&&... args) {
+inline void dump_header_infixed(struct req_state* s,
+                               const std::string_view& prefix,
+                               const std::string_view& infix,
+                               const std::string_view& sufix,
+                               Args&&... args) {
   char full_name_buf[prefix.size() + infix.size() + sufix.size() + 1];
   const auto len = snprintf(full_name_buf, sizeof(full_name_buf), "%.*s%.*s%.*s",
                             static_cast<int>(prefix.length()),
 }
 
 template <class... Args>
-static inline void dump_header_quoted(struct req_state* s,
-                                      const std::string_view& name,
-                                      const std::string_view& val) {
+inline void dump_header_quoted(struct req_state* s,
+                              const std::string_view& name,
+                              const std::string_view& val) {
   /* We need two extra bytes for quotes. */
   char qvalbuf[val.size() + 2 + 1];
   const auto len = snprintf(qvalbuf, sizeof(qvalbuf), "\"%.*s\"",
 }
 
 template <class ValueT>
-static inline void dump_header_if_nonempty(struct req_state* s,
-                                           const std::string_view& name,
-                                           const ValueT& value) {
+inline void dump_header_if_nonempty(struct req_state* s,
+                                   const std::string_view& name,
+                                   const ValueT& value) {
   if (name.length() > 0 && value.length() > 0) {
     return dump_header(s, name, value);
   }
 }
 
-static inline std::string compute_domain_uri(const struct req_state *s) {
+inline std::string compute_domain_uri(const struct req_state *s) {
   std::string uri = (!s->info.domain.empty()) ? s->info.domain :
     [&s]() -> std::string {
     RGWEnv const &env(*(s->info.env));
 extern void dump_time_header(struct req_state *s, const char *name, real_time t);
 extern void dump_last_modified(struct req_state *s, real_time t);
 extern void abort_early(struct req_state* s, RGWOp* op, int err,
-                       RGWHandler* handler);
+                       RGWHandler* handler, optional_yield y);
 extern void dump_range(struct req_state* s, uint64_t ofs, uint64_t end,
                       uint64_t total_size);
 extern void dump_continue(struct req_state *s);
 
 
 #pragma once
 
+#include "rgw/rgw_rest.h"
 
 class RGWRESTMgr_Admin : public RGWRESTMgr {
 public:
 
     return caps.check_cap("buckets", RGW_CAP_READ);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "get_bucket_info"; }
 };
 
-void RGWOp_Bucket_Info::execute()
+void RGWOp_Bucket_Info::execute(optional_yield y)
 {
   RGWBucketAdminOpState op_state;
 
   op_state.set_bucket_name(bucket);
   op_state.set_fetch_stats(fetch_stats);
 
-  op_ret = RGWBucketAdminOp::info(store, op_state, flusher, null_yield);
+  op_ret = RGWBucketAdminOp::info(store, op_state, flusher, y);
 }
 
 class RGWOp_Get_Policy : public RGWRESTOp {
     return caps.check_cap("buckets", RGW_CAP_READ);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "get_policy"; }
 };
 
-void RGWOp_Get_Policy::execute()
+void RGWOp_Get_Policy::execute(optional_yield y)
 {
   RGWBucketAdminOpState op_state;
 
     return caps.check_cap("buckets", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "check_bucket_index"; }
 };
 
-void RGWOp_Check_Bucket_Index::execute()
+void RGWOp_Check_Bucket_Index::execute(optional_yield y)
 {
   std::string bucket;
 
     return caps.check_cap("buckets", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "link_bucket"; }
 };
 
-void RGWOp_Bucket_Link::execute()
+void RGWOp_Bucket_Link::execute(optional_yield y)
 {
   std::string uid_str;
   std::string bucket;
     return caps.check_cap("buckets", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "unlink_bucket"; }
 };
 
-void RGWOp_Bucket_Unlink::execute()
+void RGWOp_Bucket_Unlink::execute(optional_yield y)
 {
   std::string uid_str;
   std::string bucket;
     return caps.check_cap("buckets", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "remove_bucket"; }
 };
 
-void RGWOp_Bucket_Remove::execute()
+void RGWOp_Bucket_Remove::execute(optional_yield y)
 {
   std::string bucket_name;
   bool delete_children;
     return caps.check_cap("buckets", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "set_bucket_quota"; }
 };
 
 #define QUOTA_INPUT_MAX_LEN 1024
 
-void RGWOp_Set_Bucket_Quota::execute()
+void RGWOp_Set_Bucket_Quota::execute(optional_yield y)
 {
   bool uid_arg_existed = false;
   std::string uid_str;
     return caps.check_cap("buckets", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "sync_bucket"; }
 };
 
-void RGWOp_Sync_Bucket::execute()
+void RGWOp_Sync_Bucket::execute(optional_yield y)
 {
   std::string bucket;
   std::string tenant;
     return caps.check_cap("buckets", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "remove_object"; }
 };
 
-void RGWOp_Object_Remove::execute()
+void RGWOp_Object_Remove::execute(optional_yield y)
 {
   std::string bucket;
   std::string object;
 
   using RGWHandler_Auth_S3::RGWHandler_Auth_S3;
   ~RGWHandler_Bucket() override = default;
 
-  int read_permissions(RGWOp*) override {
+  int read_permissions(RGWOp*, optional_yield y) override {
     return 0;
   }
 };
 
 #define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_rgw
 
-void RGWOp_ZoneGroupMap_Get::execute() {
+void RGWOp_ZoneGroupMap_Get::execute(optional_yield y) {
   op_ret = zonegroup_map.read(g_ceph_context, store->svc()->sysobj);
   if (op_ret < 0) {
     dout(5) << "failed to read zone_group map" << dendl;
     region_map.regions = zonegroup_map.zonegroups;
     region_map.master_region = zonegroup_map.master_zonegroup;
     region_map.bucket_quota = zonegroup_map.bucket_quota;
-    region_map.user_quota = zonegroup_map.user_quota;    
+    region_map.user_quota = zonegroup_map.user_quota;
     encode_json("region-map", region_map, s->formatter);
   } else {
     encode_json("zonegroup-map", zonegroup_map, s->formatter);
 
 
 #pragma once
 
+#include "rgw_auth_s3.h"
+#include "rgw_rest.h"
 #include "rgw_zone.h"
 
 class RGWOp_ZoneGroupMap_Get : public RGWRESTOp {
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("zone", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override {
     if (old_format) {
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("zone", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override {} /* store already has the info we need, just need to send response */
+  void execute(optional_yield) override {} /* store already has the info we need, just need to send response */
   void send_response() override ;
   const char* name() const override {
     return "get_zone_config";
 protected:
   RGWOp *op_get() override;
 
-  int read_permissions(RGWOp*) override {
+  int read_permissions(RGWOp*, optional_yield) override {
     return 0;
   }
 public:
 
   return RGWHandler_REST::init(store, s, cio);
 }
 
-int RGWHandler_REST_IAM::authorize(const DoutPrefixProvider* dpp)
+int RGWHandler_REST_IAM::authorize(const DoutPrefixProvider* dpp, optional_yield y)
 {
-  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s);
+  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s, y);
 }
 
 int RGWHandler_REST_IAM::init_from_header(struct req_state* s,
 
 
 #include "rgw_auth.h"
 #include "rgw_auth_filters.h"
+#include "rgw_rest.h"
 
 class RGWHandler_REST_IAM : public RGWHandler_REST {
   const rgw::auth::StrategyRegistry& auth_registry;
   int init(rgw::sal::RGWRadosStore *store,
            struct req_state *s,
            rgw::io::BasicClient *cio) override;
-  int authorize(const DoutPrefixProvider* dpp) override;
-  int postauth_init() override { return 0; }
+  int authorize(const DoutPrefixProvider* dpp, optional_yield y) override;
+  int postauth_init(optional_yield y) override { return 0; }
 };
 
 class RGWRESTMgr_IAM : public RGWRESTMgr {
 
 #define LOG_CLASS_LIST_MAX_ENTRIES (1000)
 #define dout_subsys ceph_subsys_rgw
 
-void RGWOp_MDLog_List::execute() {
+void RGWOp_MDLog_List::execute(optional_yield y) {
   string   period = s->info.args.get("period");
   string   shard = s->info.args.get("id");
   string   max_entries_str = s->info.args.get("max-entries");
   flusher.flush();
 }
 
-void RGWOp_MDLog_Info::execute() {
+void RGWOp_MDLog_Info::execute(optional_yield y) {
   num_objects = s->cct->_conf->rgw_md_log_max_shards;
-  period = store->svc()->mdlog->read_oldest_log_period(null_yield);
+  period = store->svc()->mdlog->read_oldest_log_period(y);
   op_ret = period.get_error();
 }
 
   flusher.flush();
 }
 
-void RGWOp_MDLog_ShardInfo::execute() {
+void RGWOp_MDLog_ShardInfo::execute(optional_yield y) {
   string period = s->info.args.get("period");
   string shard = s->info.args.get("id");
   string err;
   flusher.flush();
 }
 
-void RGWOp_MDLog_Delete::execute() {
+void RGWOp_MDLog_Delete::execute(optional_yield y) {
   string   marker = s->info.args.get("marker"),
            period = s->info.args.get("period"),
            shard = s->info.args.get("id"),
   op_ret = meta_log.trim(shard_id, {}, {}, {}, marker);
 }
 
-void RGWOp_MDLog_Lock::execute() {
+void RGWOp_MDLog_Lock::execute(optional_yield y) {
   string period, shard_id_str, duration_str, locker_id, zone_id;
   unsigned shard_id;
 
     op_ret = -ERR_LOCKED;
 }
 
-void RGWOp_MDLog_Unlock::execute() {
+void RGWOp_MDLog_Unlock::execute(optional_yield y) {
   string period, shard_id_str, locker_id, zone_id;
   unsigned shard_id;
 
   op_ret = meta_log.unlock(shard_id, zone_id, locker_id);
 }
 
-void RGWOp_MDLog_Notify::execute() {
+void RGWOp_MDLog_Notify::execute(optional_yield y) {
 #define LARGE_ENOUGH_BUF (128 * 1024)
 
   int r = 0;
   op_ret = 0;
 }
 
-void RGWOp_BILog_List::execute() {
+void RGWOp_BILog_List::execute(optional_yield y) {
   string tenant_name = s->info.args.get("tenant"),
          bucket_name = s->info.args.get("bucket"),
          marker = s->info.args.get("marker"),
   flusher.flush();
 }
       
-void RGWOp_BILog_Info::execute() {
+void RGWOp_BILog_Info::execute(optional_yield y) {
   string tenant_name = s->info.args.get("tenant"),
          bucket_name = s->info.args.get("bucket"),
          bucket_instance = s->info.args.get("bucket-instance");
   flusher.flush();
 }
 
-void RGWOp_BILog_Delete::execute() {
+void RGWOp_BILog_Delete::execute(optional_yield y) {
   string tenant_name = s->info.args.get("tenant"),
          bucket_name = s->info.args.get("bucket"),
          start_marker = s->info.args.get("start-marker"),
   return;
 }
 
-void RGWOp_DATALog_List::execute() {
+void RGWOp_DATALog_List::execute(optional_yield y) {
   string   shard = s->info.args.get("id");
 
   string   max_entries_str = s->info.args.get("max-entries"),
 }
 
 
-void RGWOp_DATALog_Info::execute() {
+void RGWOp_DATALog_Info::execute(optional_yield y) {
   num_objects = s->cct->_conf->rgw_data_log_num_shards;
   op_ret = 0;
 }
   flusher.flush();
 }
 
-void RGWOp_DATALog_ShardInfo::execute() {
+void RGWOp_DATALog_ShardInfo::execute(optional_yield y) {
   string shard = s->info.args.get("id");
   string err;
 
   flusher.flush();
 }
 
-void RGWOp_DATALog_Notify::execute() {
+void RGWOp_DATALog_Notify::execute(optional_yield y) {
   string  source_zone = s->info.args.get("source-zone");
 #define LARGE_ENOUGH_BUF (128 * 1024)
 
   op_ret = 0;
 }
 
-void RGWOp_DATALog_Delete::execute() {
+void RGWOp_DATALog_Delete::execute(optional_yield y) {
   string   marker = s->info.args.get("marker"),
            shard = s->info.args.get("id"),
            err;
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override { return "get_metadata_log_status"; }
 };
 
-void RGWOp_MDLog_Status::execute()
+void RGWOp_MDLog_Status::execute(optional_yield y)
 {
   auto sync = store->getRados()->get_meta_sync_manager();
   if (sync == nullptr) {
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("bilog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override { return "get_bucket_index_log_status"; }
 };
 
-void RGWOp_BILog_Status::execute()
+void RGWOp_BILog_Status::execute(optional_yield y)
 {
   const auto options = s->info.args.get("options");
   bool merge = (options == "merge");
     pipe.dest.zone = local_zone_id;
     pipe.dest.bucket = info.bucket;
 
-    ldout(s->cct, 20) << "RGWOp_BILog_Status::execute(): getting sync status for pipe=" << pipe << dendl;
+    ldout(s->cct, 20) << "RGWOp_BILog_Status::execute(optional_yield y): getting sync status for pipe=" << pipe << dendl;
 
     op_ret = rgw_bucket_sync_status(this, store, pipe, info, nullptr, &status);
 
   rgw_zone_id source_zone_id(source_zone);
 
   RGWBucketSyncPolicyHandlerRef source_handler;
-  op_ret = store->ctl()->bucket->get_sync_policy_handler(source_zone_id, source_bucket, &source_handler, null_yield);
+  op_ret = store->ctl()->bucket->get_sync_policy_handler(source_zone_id, source_bucket, &source_handler, y);
   if (op_ret < 0) {
     lderr(s->cct) << "could not get bucket sync policy handler (r=" << op_ret << ")" << dendl;
     return;
   for (auto& entry : local_dests) {
     auto pipe = entry.second;
 
-    ldout(s->cct, 20) << "RGWOp_BILog_Status::execute(): getting sync status for pipe=" << pipe << dendl;
+    ldout(s->cct, 20) << "RGWOp_BILog_Status::execute(optional_yield y): getting sync status for pipe=" << pipe << dendl;
 
     RGWBucketInfo *pinfo = &info;
     std::optional<RGWBucketInfo> opt_dest_info;
 
     if (!pipe.dest.bucket) {
       /* Uh oh, something went wrong */
-      ldout(s->cct, 20) << "ERROR: RGWOp_BILog_Status::execute(): BUG: pipe.dest.bucket was not initialized" << pipe << dendl;
+      ldout(s->cct, 20) << "ERROR: RGWOp_BILog_Status::execute(optional_yield y): BUG: pipe.dest.bucket was not initialized" << pipe << dendl;
       op_ret = -EIO;
       return;
     }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("datalog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override ;
+  void execute(optional_yield y) override ;
   void send_response() override;
   const char* name() const override { return "get_data_changes_log_status"; }
 };
 
-void RGWOp_DATALog_Status::execute()
+void RGWOp_DATALog_Status::execute(optional_yield y)
 {
   const auto source_zone = s->info.args.get("source-zone");
   auto sync = store->getRados()->get_data_sync_manager(source_zone);
 
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("bilog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
   void send_response() override;
   virtual void send_response(list<rgw_bi_log_entry>& entries, string& marker);
   virtual void send_response_end();
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "list_bucket_index_log";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("bilog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
   void send_response() override;
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "bucket_index_log_info";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("bilog", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "trim_bucket_index_log";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override {
     return "list_metadata_log";
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override {
     return "get_metadata_log_info";
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override {
     return "get_metadata_log_shard_info";
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "lock_mdlog_object";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "unlock_mdlog_object";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "mdlog_notify";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("mdlog", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "trim_metadata_log";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("datalog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override {
     return "list_data_changes_log";
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("datalog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override {
     return "get_data_changes_log_info";
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("datalog", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override {
     return "get_data_changes_log_shard_info";
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("datalog", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "datalog_notify";
   }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("datalog", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override {
     return "trim_data_changes_log";
   }
   RGWOp *op_delete() override;
   RGWOp *op_post() override;
 
-  int read_permissions(RGWOp*) override {
+  int read_permissions(RGWOp*, optional_yield) override {
     return 0;
   }
 public:
 
   }
 }
 
-void RGWOp_Metadata_Get::execute() {
+void RGWOp_Metadata_Get::execute(optional_yield y) {
   string metadata_key;
 
   frame_metadata_key(s, metadata_key);
   op_ret = 0;
 }
 
-void RGWOp_Metadata_Get_Myself::execute() {
+void RGWOp_Metadata_Get_Myself::execute(optional_yield y) {
   string owner_id;
 
   owner_id = s->owner.get_id().to_str();
   s->info.args.append("key", owner_id);
 
-  return RGWOp_Metadata_Get::execute();
+  return RGWOp_Metadata_Get::execute(y);
 }
 
-void RGWOp_Metadata_List::execute() {
+void RGWOp_Metadata_List::execute(optional_yield y) {
   string marker;
   ldout(s->cct, 16) << __func__
                    << " raw marker " << s->info.args.get("marker")
   return true;
 }
 
-void RGWOp_Metadata_Put::execute() {
+void RGWOp_Metadata_Put::execute(optional_yield y) {
   bufferlist bl;
   string metadata_key;
 
   if (op_ret < 0) {
     return;
   }
-  
+
   frame_metadata_key(s, metadata_key);
 
   RGWMDLogSyncType sync_type = RGWMDLogSyncType::APPLY_ALWAYS;
   }
 
   op_ret = store->ctl()->meta.mgr->put(metadata_key, bl, s->yield, sync_type,
-                                 &ondisk_version);
+                                      &ondisk_version);
   if (op_ret < 0) {
     dout(5) << "ERROR: can't put key: " << cpp_strerror(op_ret) << dendl;
     return;
   end_header(s);
 }
 
-void RGWOp_Metadata_Delete::execute() {
+void RGWOp_Metadata_Delete::execute(optional_yield y) {
   string metadata_key;
 
   frame_metadata_key(s, metadata_key);
 
 
 #pragma once
 
+#include "rgw/rgw_rest.h"
+#include "rgw/rgw_auth_s3.h"
+
 class RGWOp_Metadata_List : public RGWRESTOp {
 public:
   RGWOp_Metadata_List() {}
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("metadata", RGW_CAP_READ);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "list_metadata"; }
 };
 
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("metadata", RGW_CAP_READ);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "get_metadata"; }
 };
 
   RGWOp_Metadata_Get_Myself() {}
   ~RGWOp_Metadata_Get_Myself() override {}
 
-  void execute() override;
+  void execute(optional_yield y) override;
 };
 
 class RGWOp_Metadata_Put : public RGWRESTOp {
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("metadata", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override { return "set_metadata"; }
   RGWOpType get_type() override { return RGW_OP_ADMIN_SET_METADATA; }
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("metadata", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "remove_metadata"; }
 };
 
   RGWOp *op_put() override;
   RGWOp *op_delete() override;
 
-  int read_permissions(RGWOp*) override {
+  int read_permissions(RGWOp*, optional_yield y) override {
     return 0;
   }
 public:
 
 
 #define dout_subsys ceph_subsys_rgw
 
-int RGWRestOIDCProvider::verify_permission()
+int RGWRestOIDCProvider::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
     return caps.check_cap("oidc-provider", RGW_CAP_WRITE);
 }
 
-int RGWCreateOIDCProvider::verify_permission()
+int RGWCreateOIDCProvider::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return 0;
 }
 
-void RGWCreateOIDCProvider::execute()
+void RGWCreateOIDCProvider::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
 
 }
 
-void RGWDeleteOIDCProvider::execute()
+void RGWDeleteOIDCProvider::execute(optional_yield y)
 {
   RGWOIDCProvider provider(s->cct, store->getRados()->pctl, provider_arn, s->user->get_tenant());
   op_ret = provider.delete_obj();
   }
 }
 
-void RGWGetOIDCProvider::execute()
+void RGWGetOIDCProvider::execute(optional_yield y)
 {
   RGWOIDCProvider provider(s->cct, store->getRados()->pctl, provider_arn, s->user->get_tenant());
   op_ret = provider.get();
   }
 }
 
-int RGWListOIDCProviders::verify_permission()
+int RGWListOIDCProviders::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return 0;
 }
 
-void RGWListOIDCProviders::execute()
+void RGWListOIDCProviders::execute(optional_yield y)
 {
   vector<RGWOIDCProvider> result;
   op_ret = RGWOIDCProvider::get_providers(store->getRados(), s->user->get_tenant(), result);
 
 
 #pragma once
 
+#include "rgw_rest.h"
 #include "rgw_oidc_provider.h"
 
 class RGWRestOIDCProvider : public RGWRESTOp {
   string provider_url; //'iss' field in JWT
   string provider_arn;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void send_response() override;
   virtual uint64_t get_op() = 0;
 };
 class RGWCreateOIDCProvider : public RGWRestOIDCProviderWrite {
 public:
   RGWCreateOIDCProvider() = default;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "create_oidc_provider"; }
   RGWOpType get_type() override { return RGW_OP_CREATE_OIDC_PROVIDER; }
-  uint64_t get_op() { return rgw::IAM::iamCreateOIDCProvider; }
+  uint64_t get_op() override { return rgw::IAM::iamCreateOIDCProvider; }
 };
 
 class RGWDeleteOIDCProvider : public RGWRestOIDCProviderWrite {
 public:
   RGWDeleteOIDCProvider() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "delete_oidc_provider"; }
   RGWOpType get_type() override { return RGW_OP_DELETE_OIDC_PROVIDER; }
-  uint64_t get_op() { return rgw::IAM::iamDeleteOIDCProvider; }
+  uint64_t get_op() override { return rgw::IAM::iamDeleteOIDCProvider; }
 };
 
 class RGWGetOIDCProvider : public RGWRestOIDCProviderRead {
 public:
   RGWGetOIDCProvider() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "get_oidc_provider"; }
   RGWOpType get_type() override { return RGW_OP_GET_OIDC_PROVIDER; }
-  uint64_t get_op() { return rgw::IAM::iamGetOIDCProvider; }
+  uint64_t get_op() override { return rgw::IAM::iamGetOIDCProvider; }
 };
 
 class RGWListOIDCProviders : public RGWRestOIDCProviderRead {
 public:
   RGWListOIDCProviders() = default;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "list_oidc_providers"; }
   RGWOpType get_type() override { return RGW_OP_LIST_OIDC_PROVIDERS; }
-  uint64_t get_op() { return rgw::IAM::iamListOIDCProviders; }
+  uint64_t get_op() override { return rgw::IAM::iamListOIDCProviders; }
 };
 
   return nullptr;
 }
 
-int RGWHandler_REST_PSTopic_AWS::authorize(const DoutPrefixProvider* dpp) {
+int RGWHandler_REST_PSTopic_AWS::authorize(const DoutPrefixProvider* dpp, optional_yield y) {
   /*if (s->info.args.exists("Action") && s->info.args.get("Action").find("Topic") != std::string::npos) {
       // TODO: some topic specific authorization
       return 0;
   }*/
-  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s);
+  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s, y);
 }
 
 
 
 public:
   const char* name() const override { return "pubsub_notification_create_s3"; }
-  void execute() override;
+  void execute(optional_yield) override;
 };
 
-void RGWPSCreateNotif_ObjStore_S3::execute() {
+void RGWPSCreateNotif_ObjStore_S3::execute(optional_yield y) {
   op_ret = get_params_from_body();
   if (op_ret < 0) {
     return;
   }
 
 public:
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "pubsub_notification_delete_s3"; }
 };
 
-void RGWPSDeleteNotif_ObjStore_S3::execute() {
+void RGWPSDeleteNotif_ObjStore_S3::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   }
 
 public:
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override {
     if (op_ret) {
       set_req_state_err(s, op_ret);
   const char* name() const override { return "pubsub_notifications_get_s3"; }
 };
 
-void RGWPSListNotifs_ObjStore_S3::execute() {
+void RGWPSListNotifs_ObjStore_S3::execute(optional_yield y) {
   ups.emplace(store, s->owner.get_id());
   auto b = ups->get_bucket(bucket_info.bucket);
   ceph_assert(b);
 
 // s3 compliant notification handler factory
 class RGWHandler_REST_PSNotifs_S3 : public RGWHandler_REST_S3 {
 protected:
-  int init_permissions(RGWOp* op) override {return 0;}
-  int read_permissions(RGWOp* op) override {return 0;}
+  int init_permissions(RGWOp* op, optional_yield y) override {return 0;}
+  int read_permissions(RGWOp* op, optional_yield y) override {return 0;}
   bool supports_quota() override {return false;}
   RGWOp* op_get() override;
   RGWOp* op_put() override;
       auth_registry(_auth_registry),
       post_body(_post_body) {}
   virtual ~RGWHandler_REST_PSTopic_AWS() = default;
-  int postauth_init() override { return 0; }
-  int authorize(const DoutPrefixProvider* dpp) override;
+  int postauth_init(optional_yield) override { return 0; }
+  int authorize(const DoutPrefixProvider* dpp, optional_yield y) override;
 };
-
 
     }
     return false;
 }
-void RGWPSCreateTopicOp::execute() {
+void RGWPSCreateTopicOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   ldout(s->cct, 20) << "successfully created topic '" << topic_name << "'" << dendl;
 }
 
-void RGWPSListTopicsOp::execute() {
+void RGWPSListTopicsOp::execute(optional_yield y) {
   ups.emplace(store, s->owner.get_id());
   op_ret = ups->get_user_topics(&result);
   // if there are no topics it is not considered an error
   ldout(s->cct, 20) << "successfully got topics" << dendl;
 }
 
-void RGWPSGetTopicOp::execute() {
+void RGWPSGetTopicOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   ldout(s->cct, 1) << "successfully got topic '" << topic_name << "'" << dendl;
 }
 
-void RGWPSDeleteTopicOp::execute() {
+void RGWPSDeleteTopicOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   ldout(s->cct, 1) << "successfully removed topic '" << topic_name << "'" << dendl;
 }
 
-void RGWPSCreateSubOp::execute() {
+void RGWPSCreateSubOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   ldout(s->cct, 20) << "successfully created subscription '" << sub_name << "'" << dendl;
 }
 
-void RGWPSGetSubOp::execute() {
+void RGWPSGetSubOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   ldout(s->cct, 20) << "successfully got subscription '" << sub_name << "'" << dendl;
 }
 
-void RGWPSDeleteSubOp::execute() {
+void RGWPSDeleteSubOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   ldout(s->cct, 20) << "successfully removed subscription '" << sub_name << "'" << dendl;
 }
 
-void RGWPSAckSubEventOp::execute() {
+void RGWPSAckSubEventOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   ldout(s->cct, 20) << "successfully acked event on subscription '" << sub_name << "'" << dendl;
 }
 
-void RGWPSPullSubEventsOp::execute() {
+void RGWPSPullSubEventsOp::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
 }
 
 
-int RGWPSCreateNotifOp::verify_permission() {
+int RGWPSCreateNotifOp::verify_permission(optional_yield y) {
   int ret = get_params();
   if (ret < 0) {
     return ret;
   const auto& id = s->owner.get_id();
 
   ret = store->getRados()->get_bucket_info(store->svc(), id.tenant, bucket_name,
-                               bucket_info, nullptr, null_yield, nullptr);
+                               bucket_info, nullptr, y, nullptr);
   if (ret < 0) {
     ldout(s->cct, 1) << "failed to get bucket info, cannot verify ownership" << dendl;
     return ret;
   return 0;
 }
 
-int RGWPSDeleteNotifOp::verify_permission() {
+int RGWPSDeleteNotifOp::verify_permission(optional_yield y) {
   int ret = get_params();
   if (ret < 0) {
     return ret;
   }
 
   ret = store->getRados()->get_bucket_info(store->svc(), s->owner.get_id().tenant, bucket_name,
-                               bucket_info, nullptr, null_yield, nullptr);
+                               bucket_info, nullptr, y, nullptr);
   if (ret < 0) {
     return ret;
   }
   return 0;
 }
 
-int RGWPSListNotifsOp::verify_permission() {
+int RGWPSListNotifsOp::verify_permission(optional_yield y) {
   int ret = get_params();
   if (ret < 0) {
     return ret;
   }
 
   ret = store->getRados()->get_bucket_info(store->svc(), s->owner.get_id().tenant, bucket_name,
-                               bucket_info, nullptr, null_yield, nullptr);
+                               bucket_info, nullptr, y, nullptr);
   if (ret < 0) {
     return ret;
   }
 
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield) override;
 
   const char* name() const override { return "pubsub_topic_create"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_TOPIC_CREATE; }
   rgw_pubsub_user_topics result;
 
 public:
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield) override;
 
   const char* name() const override { return "pubsub_topics_list"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_TOPICS_LIST; }
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override {
+  int verify_permission(optional_yield y) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "pubsub_topic_get"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_TOPIC_GET; }
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "pubsub_topic_delete"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_TOPIC_DELETE; }
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "pubsub_subscription_create"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_SUB_CREATE; }
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "pubsub_subscription_get"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_SUB_GET; }
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "pubsub_subscription_delete"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_SUB_DELETE; }
 public:
   RGWPSAckSubEventOp() {}
 
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "pubsub_subscription_ack"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_SUB_ACK; }
 public:
   RGWPSPullSubEventsOp() {}
 
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "pubsub_subscription_pull"; }
   RGWOpType get_type() override { return RGW_OP_PUBSUB_SUB_PULL; }
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
 
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
 
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   virtual int get_params() = 0;
 
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
 
   void pre_exec() override {
     rgw_bucket_object_pre_exec(s);
   RGWOpType get_type() override { return RGW_OP_PUBSUB_NOTIF_LIST; }
   uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
 };
-
 
   RGWPeriod period;
   std::ostringstream error_stream;
  public:
-  int verify_permission() override { return 0; }
+  int verify_permission(optional_yield) override { return 0; }
   void send_response() override;
 };
 
 // GET /admin/realm/period
 class RGWOp_Period_Get : public RGWOp_Period_Base {
  public:
-  void execute() override;
+  void execute(optional_yield y) override;
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("zone", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_caps());
   }
   const char* name() const override { return "get_period"; }
 };
 
-void RGWOp_Period_Get::execute()
+void RGWOp_Period_Get::execute(optional_yield y)
 {
   string realm_id, realm_name, period_id;
   epoch_t epoch = 0;
 // POST /admin/realm/period
 class RGWOp_Period_Post : public RGWOp_Period_Base {
  public:
-  void execute() override;
+  void execute(optional_yield y) override;
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("zone", RGW_CAP_WRITE);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_caps());
   }
   const char* name() const override { return "post_period"; }
 };
 
-void RGWOp_Period_Post::execute()
+void RGWOp_Period_Post::execute(optional_yield y)
 {
   auto cct = store->ctx();
 
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("zone", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override { return "get_realm"; }
 };
 
-void RGWOp_Realm_Get::execute()
+void RGWOp_Realm_Get::execute(optional_yield y)
 {
   string id;
   RESTArgs::get_string(s, "id", id, &id);
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("zone", RGW_CAP_READ);
   }
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return check_caps(s->user->get_caps());
   }
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   const char* name() const override { return "list_realms"; }
 };
 
-void RGWOp_Realm_List::execute()
+void RGWOp_Realm_List::execute(optional_yield y)
 {
   {
     // read default realm
 
 
 #define dout_subsys ceph_subsys_rgw
 
-int RGWRestRole::verify_permission()
+int RGWRestRole::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
     return caps.check_cap("roles", RGW_CAP_WRITE);
 }
 
-int RGWCreateRole::verify_permission()
+int RGWCreateRole::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return 0;
 }
 
-void RGWCreateRole::execute()
+void RGWCreateRole::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWDeleteRole::execute()
+void RGWDeleteRole::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   s->formatter->close_section();
 }
 
-int RGWGetRole::verify_permission()
+int RGWGetRole::verify_permission(optional_yield y)
 {
   return 0;
 }
   return 0;
 }
 
-void RGWGetRole::execute()
+void RGWGetRole::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWModifyRole::execute()
+void RGWModifyRole::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   s->formatter->close_section();
 }
 
-int RGWListRoles::verify_permission()
+int RGWListRoles::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return 0;
 }
 
-void RGWListRoles::execute()
+void RGWListRoles::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWPutRolePolicy::execute()
+void RGWPutRolePolicy::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWGetRolePolicy::execute()
+void RGWGetRolePolicy::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWListRolePolicies::execute()
+void RGWListRolePolicies::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWDeleteRolePolicy::execute()
+void RGWDeleteRolePolicy::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
 
 
 #pragma once
 
+#include "common/async/yield_context.h"
+
 #include "rgw_role.h"
+#include "rgw_rest.h"
 
 class RGWRestRole : public RGWRESTOp {
 protected:
   string max_session_duration;
   RGWRole _role;
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void send_response() override;
   virtual uint64_t get_op() = 0;
 };
 class RGWCreateRole : public RGWRoleWrite {
 public:
   RGWCreateRole() = default;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "create_role"; }
   RGWOpType get_type() override { return RGW_OP_CREATE_ROLE; }
-  uint64_t get_op() { return rgw::IAM::iamCreateRole; }
+  uint64_t get_op() override { return rgw::IAM::iamCreateRole; }
 };
 
 class RGWDeleteRole : public RGWRoleWrite {
 public:
   RGWDeleteRole() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "delete_role"; }
   RGWOpType get_type() override { return RGW_OP_DELETE_ROLE; }
-  uint64_t get_op() { return rgw::IAM::iamDeleteRole; }
+  uint64_t get_op() override { return rgw::IAM::iamDeleteRole; }
 };
 
 class RGWGetRole : public RGWRoleRead {
   int _verify_permission(const RGWRole& role);
 public:
   RGWGetRole() = default;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "get_role"; }
   RGWOpType get_type() override { return RGW_OP_GET_ROLE; }
-  uint64_t get_op() { return rgw::IAM::iamGetRole; }
+  uint64_t get_op() override { return rgw::IAM::iamGetRole; }
 };
 
 class RGWModifyRole : public RGWRoleWrite {
 public:
   RGWModifyRole() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "modify_role"; }
   RGWOpType get_type() override { return RGW_OP_MODIFY_ROLE; }
-  uint64_t get_op() { return rgw::IAM::iamModifyRole; }
+  uint64_t get_op() override { return rgw::IAM::iamModifyRole; }
 };
 
 class RGWListRoles : public RGWRoleRead {
 public:
   RGWListRoles() = default;
-  int verify_permission() override;
-  void execute() override;
+  int verify_permission(optional_yield y) override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "list_roles"; }
   RGWOpType get_type() override { return RGW_OP_LIST_ROLES; }
-  uint64_t get_op() { return rgw::IAM::iamListRoles; }
+  uint64_t get_op() override { return rgw::IAM::iamListRoles; }
 };
 
 class RGWPutRolePolicy : public RGWRoleWrite {
 public:
   RGWPutRolePolicy() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "put_role_policy"; }
   RGWOpType get_type() override { return RGW_OP_PUT_ROLE_POLICY; }
-  uint64_t get_op() { return rgw::IAM::iamPutRolePolicy; }
+  uint64_t get_op() override { return rgw::IAM::iamPutRolePolicy; }
 };
 
 class RGWGetRolePolicy : public RGWRoleRead {
 public:
   RGWGetRolePolicy() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "get_role_policy"; }
   RGWOpType get_type() override { return RGW_OP_GET_ROLE_POLICY; }
-  uint64_t get_op() { return rgw::IAM::iamGetRolePolicy; }
+  uint64_t get_op() override { return rgw::IAM::iamGetRolePolicy; }
 };
 
 class RGWListRolePolicies : public RGWRoleRead {
 public:
   RGWListRolePolicies() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "list_role_policies"; }
   RGWOpType get_type() override { return RGW_OP_LIST_ROLE_POLICIES; }
-  uint64_t get_op() { return rgw::IAM::iamListRolePolicies; }
+  uint64_t get_op() override { return rgw::IAM::iamListRolePolicies; }
 };
 
 class RGWDeleteRolePolicy : public RGWRoleWrite {
 public:
   RGWDeleteRolePolicy() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "delete_role_policy"; }
   RGWOpType get_type() override { return RGW_OP_DELETE_ROLE_POLICY; }
-  uint64_t get_op() { return rgw::IAM::iamDeleteRolePolicy; }
+  uint64_t get_op() override { return rgw::IAM::iamDeleteRolePolicy; }
 };
 
   }
 }
 
-int RGWGetObj_ObjStore_S3Website::send_response_data_error()
+int RGWGetObj_ObjStore_S3Website::send_response_data_error(optional_yield y)
 {
-  return RGWGetObj_ObjStore_S3::send_response_data_error();
+  return RGWGetObj_ObjStore_S3::send_response_data_error(y);
 }
 
-int RGWGetObj_ObjStore_S3::get_params()
+int RGWGetObj_ObjStore_S3::get_params(optional_yield y)
 {
   // for multisite sync requests, only read the slo manifest itself, rather than
   // all of the data from its parts. the parts will sync as separate objects
     skip_decrypt = s->info.args.exists(RGW_SYS_PARAM_PREFIX "skip-decrypt");
   }
 
-  return RGWGetObj_ObjStore::get_params();
+  return RGWGetObj_ObjStore::get_params(y);
 }
 
-int RGWGetObj_ObjStore_S3::send_response_data_error()
+int RGWGetObj_ObjStore_S3::send_response_data_error(optional_yield y)
 {
   bufferlist bl;
   return send_response_data(bl, 0 , 0);
   }
   return res;
 }
-int RGWGetObj_ObjStore_S3::verify_requester(const rgw::auth::StrategyRegistry& auth_registry) 
+int RGWGetObj_ObjStore_S3::verify_requester(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y) 
 {
   int ret = -EINVAL;
-  ret = RGWOp::verify_requester(auth_registry);
+  ret = RGWOp::verify_requester(auth_registry, y);
   if(!s->user->get_caps().check_cap("amz-cache", RGW_CAP_READ) && !ret && s->info.env->exists("HTTP_X_AMZ_CACHE"))
-    ret = override_range_hdr(auth_registry);
+    ret = override_range_hdr(auth_registry, y);
   return ret;
 }
-int RGWGetObj_ObjStore_S3::override_range_hdr(const rgw::auth::StrategyRegistry& auth_registry)
+
+int RGWGetObj_ObjStore_S3::override_range_hdr(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y)
 {
   int ret = -EINVAL;
   ldpp_dout(this, 10) << "cache override headers" << dendl;
     rgw_env->set(std::move(key), std::string(*v));
     ldpp_dout(this, 10) << "after splitting cache kv key: " << key  << " " << rgw_env->get(key.c_str())  << dendl;
   }
-  ret = RGWOp::verify_requester(auth_registry);
+  ret = RGWOp::verify_requester(auth_registry, y);
   if(!ret && backup_range) {
     rgw_env->set("HTTP_RANGE",backup_range);
   } else {
 }
 
 
-int RGWPutObjTags_ObjStore_S3::get_params()
+int RGWPutObjTags_ObjStore_S3::get_params(optional_yield y)
 {
   RGWXMLParser parser;
 
   }
 }
 
-int RGWPutBucketTags_ObjStore_S3::get_params()
+int RGWPutBucketTags_ObjStore_S3::get_params(optional_yield y)
 {
   RGWXMLParser parser;
 
   }
 }
 
-int RGWPutBucketReplication_ObjStore_S3::get_params()
+int RGWPutBucketReplication_ObjStore_S3::get_params(optional_yield y)
 {
   RGWXMLParser parser;
 
   }
 }
 
-int RGWGetUsage_ObjStore_S3::get_params()
+int RGWGetUsage_ObjStore_S3::get_params(optional_yield y)
 {
   start_date = s->info.args.get("start-date");
   end_date = s->info.args.get("end-date");
   return 0;
 }
 
-int RGWListBucket_ObjStore_S3::get_params()
+int RGWListBucket_ObjStore_S3::get_params(optional_yield y)
 {
   int ret = get_common_params();
   if (ret < 0) {
   return 0;
 }
 
-int RGWListBucket_ObjStore_S3v2::get_params()
+int RGWListBucket_ObjStore_S3v2::get_params(optional_yield y)
 {
 int ret = get_common_params();
 if (ret < 0) {
   }
 };
 
-int RGWSetBucketVersioning_ObjStore_S3::get_params()
+int RGWSetBucketVersioning_ObjStore_S3::get_params(optional_yield y)
 {
   int r = 0;
   bufferlist data;
         mfa_status = true;
         break;
       default:
-        ldpp_dout(this, 0) << "ERROR: RGWSetBucketVersioning_ObjStore_S3::get_params(): unexpected switch case mfa_status=" << status_conf.mfa_status << dendl;
+        ldpp_dout(this, 0) << "ERROR: RGWSetBucketVersioning_ObjStore_S3::get_params(optional_yield y): unexpected switch case mfa_status=" << status_conf.mfa_status << dendl;
         r = -EIO;
     }
   } else if (status_conf.retcode < 0) {
   end_header(s, this, "application/xml");
 }
 
-int RGWSetBucketWebsite_ObjStore_S3::get_params()
+int RGWSetBucketWebsite_ObjStore_S3::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
 
   }
 };
 
-int RGWCreateBucket_ObjStore_S3::get_params()
+int RGWCreateBucket_ObjStore_S3::get_params(optional_yield y)
 {
   RGWAccessControlPolicy_S3 s3policy(s->cct);
   bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names;
   }
 }
 
-int RGWPutObj_ObjStore_S3::get_params()
+int RGWPutObj_ObjStore_S3::get_params(optional_yield y)
 {
   if (!s->length)
     return -ERR_LENGTH_REQUIRED;
     position = uint64_t(pos_tmp);
   }
 
-  return RGWPutObj_ObjStore::get_params();
+  return RGWPutObj_ObjStore::get_params(y);
 }
 
 int RGWPutObj_ObjStore_S3::get_data(bufferlist& bl)
   return content_type;
 }
 
-int RGWPostObj_ObjStore_S3::get_params()
+int RGWPostObj_ObjStore_S3::get_params(optional_yield y)
 {
-  op_ret = RGWPostObj_ObjStore::get_params();
+  op_ret = RGWPostObj_ObjStore::get_params(y);
   if (op_ret < 0) {
     return op_ret;
   }
     attrs[attr_name] = attr_bl;
   }
 
-  int r = get_policy();
+  int r = get_policy(y);
   if (r < 0)
     return r;
 
   return 0;
 }
 
-int RGWPostObj_ObjStore_S3::get_policy()
+int RGWPostObj_ObjStore_S3::get_policy(optional_yield y)
 {
   if (part_bl(parts, "policy", &s->auth.s3_postobj_creds.encoded_policy)) {
     bool aws4_auth = false;
     /* FIXME: this is a makeshift solution. The browser upload authentication will be
      * handled by an instance of rgw::auth::Completer spawned in Handler's authorize()
      * method. */
-    const int ret = rgw::auth::Strategy::apply(this, auth_registry_ptr->get_s3_post(), s);
+    const int ret = rgw::auth::Strategy::apply(this, auth_registry_ptr->get_s3_post(), s, y);
     if (ret != 0) {
       return -EACCES;
     } else {
   return res;
 }
 
-int RGWDeleteObj_ObjStore_S3::get_params()
+int RGWDeleteObj_ObjStore_S3::get_params(optional_yield y)
 {
   const char *if_unmod = s->info.env->get("HTTP_X_AMZ_DELETE_IF_UNMODIFIED_SINCE");
 
   return 0;
 }
 
-int RGWCopyObj_ObjStore_S3::get_params()
+int RGWCopyObj_ObjStore_S3::get_params(optional_yield y)
 {
   if_mod = s->info.env->get("HTTP_X_AMZ_COPY_IF_MODIFIED_SINCE");
   if_unmod = s->info.env->get("HTTP_X_AMZ_COPY_IF_UNMODIFIED_SINCE");
   dump_body(s, acls);
 }
 
-int RGWPutACLs_ObjStore_S3::get_params()
+int RGWPutACLs_ObjStore_S3::get_params(optional_yield y)
 {
-  int ret =  RGWPutACLs_ObjStore::get_params();
+  int ret =  RGWPutACLs_ObjStore::get_params(y);
   if (ret >= 0) {
     const int ret_auth = do_aws4_auth_completion();
     if (ret_auth < 0) {
   dump_start(s);
 }
 
-void RGWGetLC_ObjStore_S3::execute()
+void RGWGetLC_ObjStore_S3::execute(optional_yield y)
 {
   config.set_ctx(s->cct);
 
   }
 }
 
-int RGWPutCORS_ObjStore_S3::get_params()
+int RGWPutCORS_ObjStore_S3::get_params(optional_yield y)
 {
   RGWCORSXMLParser_S3 parser(s->cct);
   RGWCORSConfiguration_S3 *cors_config;
   }
 };
 
-int RGWSetRequestPayment_ObjStore_S3::get_params()
+int RGWSetRequestPayment_ObjStore_S3::get_params(optional_yield y)
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
 
   end_header(s);
 }
 
-int RGWInitMultipart_ObjStore_S3::get_params()
+int RGWInitMultipart_ObjStore_S3::get_params(optional_yield y)
 {
   RGWAccessControlPolicy_S3 s3policy(s->cct);
   op_ret = create_s3_policy(s, store, s3policy, s->owner);
   return res;
 }
 
-int RGWCompleteMultipart_ObjStore_S3::get_params()
+int RGWCompleteMultipart_ObjStore_S3::get_params(optional_yield y)
 {
-  int ret = RGWCompleteMultipart_ObjStore::get_params();
+  int ret = RGWCompleteMultipart_ObjStore::get_params(y);
   if (ret < 0) {
     return ret;
   }
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-int RGWDeleteMultiObj_ObjStore_S3::get_params()
+int RGWDeleteMultiObj_ObjStore_S3::get_params(optional_yield y)
 {
-  int ret = RGWDeleteMultiObj_ObjStore::get_params();
+  int ret = RGWDeleteMultiObj_ObjStore::get_params(y);
   if (ret < 0) {
     return ret;
   }
   rgw_flush_formatter(s, &f);
 }
 
-int RGWConfigBucketMetaSearch_ObjStore_S3::get_params()
+int RGWConfigBucketMetaSearch_ObjStore_S3::get_params(optional_yield y)
 {
   auto iter = s->info.x_meta_map.find("x-amz-meta-search");
   if (iter == s->info.x_meta_map.end()) {
 }
 
 
-int RGWPutObjRetention_ObjStore_S3::get_params()
+int RGWPutObjRetention_ObjStore_S3::get_params(optional_yield y)
 {
   const char *bypass_gov_header = s->info.env->get("HTTP_X_AMZ_BYPASS_GOVERNANCE_RETENTION");
   if (bypass_gov_header) {
   return 0;
 }
 
-static int verify_mfa(rgw::sal::RGWRadosStore *store, RGWUserInfo *user, const string& mfa_str, bool *verified, const DoutPrefixProvider *dpp)
+static int verify_mfa(rgw::sal::RGWRadosStore *store, RGWUserInfo *user,
+                     const string& mfa_str, bool *verified, const DoutPrefixProvider *dpp, optional_yield y)
 {
   vector<string> params;
   get_str_vec(mfa_str, " ", params);
     return -EACCES;
   }
 
-  int ret = store->svc()->cls->mfa.check_mfa(user->user_id, serial, pin, null_yield);
+  int ret = store->svc()->cls->mfa.check_mfa(user->user_id, serial, pin, y);
   if (ret < 0) {
     ldpp_dout(dpp, 20) << "NOTICE: failed to check MFA, serial=" << serial << dendl;
     return -EACCES;
   return 0;
 }
 
-int RGWHandler_REST_S3::postauth_init()
+int RGWHandler_REST_S3::postauth_init(optional_yield y)
 {
   struct req_init_state *t = &s->init_state;
 
 
   const char *mfa = s->info.env->get("HTTP_X_AMZ_MFA");
   if (mfa) {
-    ret = verify_mfa(store, &s->user->get_info(), string(mfa), &s->mfa_verified, s);
+    ret = verify_mfa(store, &s->user->get_info(), string(mfa), &s->mfa_verified, s, y);
   }
 
   return 0;
   return RGWHandler_REST::init(store, s, cio);
 }
 
-int RGWHandler_REST_S3::authorize(const DoutPrefixProvider *dpp)
+int RGWHandler_REST_S3::authorize(const DoutPrefixProvider *dpp, optional_yield y)
 {
   if (s->info.args.exists("Action") && s->info.args.get("Action") == "AssumeRoleWithWebIdentity") {
-    return RGW_Auth_STS::authorize(dpp, store, auth_registry, s);
+    return RGW_Auth_STS::authorize(dpp, store, auth_registry, s, y);
   }
-  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s);
+  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s, y);
 }
 
 enum class AwsVersion {
 int RGW_Auth_S3::authorize(const DoutPrefixProvider *dpp,
                            rgw::sal::RGWRadosStore* const store,
                            const rgw::auth::StrategyRegistry& auth_registry,
-                           struct req_state* const s)
+                           struct req_state* const s, optional_yield y)
 {
 
   /* neither keystone and rados enabled; warn and exit! */
     return -EPERM;
   }
 
-  const auto ret = rgw::auth::Strategy::apply(dpp, auth_registry.get_s3_main(), s);
+  const auto ret = rgw::auth::Strategy::apply(dpp, auth_registry.get_s3_main(), s, y);
   if (ret == 0) {
     /* Populate the owner info. */
     s->owner.set_id(s->user->get_id());
   return get_obj_op(false);
 }
 
-int RGWHandler_REST_S3Website::serve_errordoc(int http_ret, const string& errordoc_key) {
+int RGWHandler_REST_S3Website::serve_errordoc(int http_ret, const string& errordoc_key, optional_yield y) {
   int ret = 0;
   s->formatter->reset(); /* Try to throw it all away */
 
   getop->if_nomatch = NULL;
   s->object = store->get_object(errordoc_key);
 
-  ret = init_permissions(getop.get());
+  ret = init_permissions(getop.get(), y);
   if (ret < 0) {
     ldpp_dout(s, 20) << "serve_errordoc failed, init_permissions ret=" << ret << dendl;
     return -1; // Trigger double error handler
   }
 
-  ret = read_permissions(getop.get());
+  ret = read_permissions(getop.get(), y);
   if (ret < 0) {
     ldpp_dout(s, 20) << "serve_errordoc failed, read_permissions ret=" << ret << dendl;
     return -1; // Trigger double error handler
      getop->set_custom_http_response(http_ret);
   }
 
-  ret = getop->init_processing();
+  ret = getop->init_processing(y);
   if (ret < 0) {
     ldpp_dout(s, 20) << "serve_errordoc failed, init_processing ret=" << ret << dendl;
     return -1; // Trigger double error handler
     return -1; // Trigger double error handler
   }
 
-  ret = getop->verify_permission();
+  ret = getop->verify_permission(y);
   if (ret < 0) {
     ldpp_dout(s, 20) << "serve_errordoc failed, verify_permission ret=" << ret << dendl;
     return -1; // Trigger double error handler
    *   x-amz-error-message: The specified key does not exist.
    *   x-amz-error-detail-Key: foo
    */
-  getop->execute();
+  getop->execute(y);
   getop->complete();
   return 0;
-
 }
 
 int RGWHandler_REST_S3Website::error_handler(int err_no,
-                                           string* error_content) {
+                                            string* error_content,
+                                            optional_yield y) {
   int new_err_no = -1;
   rgw_http_errors::const_iterator r = rgw_http_s3_errors.find(err_no > 0 ? err_no : -err_no);
   int http_error_code = -1;
        On success, it will return zero, and no further content should be sent to the socket
        On failure, we need the double-error handler
      */
-    new_err_no = RGWHandler_REST_S3Website::serve_errordoc(http_error_code, s->bucket->get_info().website_conf.error_doc);
+    new_err_no = RGWHandler_REST_S3Website::serve_errordoc(http_error_code, s->bucket->get_info().website_conf.error_doc, y);
     if (new_err_no && new_err_no != -1) {
       err_no = new_err_no;
     }
 }
 
 AWSEngine::result_t
-AWSEngine::authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const
+AWSEngine::authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const
 {
   /* Small reminder: an ver_abstractor is allowed to throw! */
   const auto auth_data = ver_abstractor.get_auth_data(s);
 {
 }
 
-int RGWSelectObj_ObjStore_S3::get_params()
+int RGWSelectObj_ObjStore_S3::get_params(optional_yield y)
 {
 
   //retrieve s3-select query from payload
     return status;
   }
 
-  return RGWGetObj_ObjStore_S3::get_params();
+  return RGWGetObj_ObjStore_S3::get_params(y);
 }
 
 void RGWSelectObj_ObjStore_S3::encode_short(char* buff, uint16_t s, int& i)
 
   // just the status line altered.
   int custom_http_ret = 0;
   std::map<std::string, std::string> crypt_http_responses;
-  int override_range_hdr(const rgw::auth::StrategyRegistry& auth_registry);
+  int override_range_hdr(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y);
 public:
   RGWGetObj_ObjStore_S3() {}
   ~RGWGetObj_ObjStore_S3() override {}
 
-  int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) override;
-  int get_params() override;
-  int send_response_data_error() override;
+  int verify_requester(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y) override;
+  int get_params(optional_yield y) override;
+  int send_response_data_error(optional_yield y) override;
   int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
   void set_custom_http_response(int http_ret) { custom_http_ret = http_ret; }
   int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
   RGWPutObjTags_ObjStore_S3() {}
   ~RGWPutObjTags_ObjStore_S3() {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
 class RGWPutBucketTags_ObjStore_S3 : public RGWPutBucketTags_ObjStore
 {
 public:
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
 class RGWPutBucketReplication_ObjStore_S3 : public RGWPutBucketReplication_ObjStore
 {
 public:
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWListBuckets_ObjStore_S3() {}
   ~RGWListBuckets_ObjStore_S3() override {}
 
-  int get_params() override {
+  int get_params(optional_yield y) override {
     limit = -1; /* no limit */
     return 0;
   }
   RGWGetUsage_ObjStore_S3() {}
   ~RGWGetUsage_ObjStore_S3() override {}
 
-  int get_params() override ;
+  int get_params(optional_yield y) override ;
   void send_response() override;
 };
 
   }
   ~RGWListBucket_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
   void send_versioned_response();
 };
   }
   ~RGWListBucket_ObjStore_S3v2() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
   void send_versioned_response();
 };
   RGWSetBucketVersioning_ObjStore_S3() {}
   ~RGWSetBucketVersioning_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWSetBucketWebsite_ObjStore_S3() {}
   ~RGWSetBucketWebsite_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWCreateBucket_ObjStore_S3() {}
   ~RGWCreateBucket_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWPutObj_ObjStore_S3() {}
   ~RGWPutObj_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   int get_data(bufferlist& bl) override;
   void send_response() override;
 
 
   const rgw::auth::StrategyRegistry* auth_registry_ptr = nullptr;
 
-  int get_policy();
+  int get_policy(optional_yield y);
   int get_tags();
   void rebuild_key(rgw::sal::RGWObject* obj);
 
   RGWPostObj_ObjStore_S3() {}
   ~RGWPostObj_ObjStore_S3() override {}
 
-  int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) override {
+  int verify_requester(const rgw::auth::StrategyRegistry& auth_registry, optional_yield y) override {
     auth_registry_ptr = &auth_registry;
-    return RGWPostObj_ObjStore::verify_requester(auth_registry);
+    return RGWPostObj_ObjStore::verify_requester(auth_registry, y);
   }
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   int complete_get_params();
 
   void send_response() override;
   RGWDeleteObj_ObjStore_S3() {}
   ~RGWDeleteObj_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   ~RGWCopyObj_ObjStore_S3() override {}
 
   int init_dest_policy() override;
-  int get_params() override;
-  int check_storage_class(const rgw_placement_rule& src_placement);
+  int get_params(optional_yield y) override;
+  int check_storage_class(const rgw_placement_rule& src_placement) override;
   void send_partial_response(off_t ofs) override;
   void send_response() override;
 };
 
   int get_policy_from_state(rgw::sal::RGWRadosStore *store, struct req_state *s, stringstream& ss) override;
   void send_response() override;
-  int get_params() override;
+  int get_params(optional_yield y) override;
 };
 
 class RGWGetLC_ObjStore_S3 : public RGWGetLC_ObjStore {
 public:
   RGWGetLC_ObjStore_S3() {}
   ~RGWGetLC_ObjStore_S3() override {}
-  void execute() override;
+  void execute(optional_yield y) override;
 
  void send_response() override;
 };
 public:
   RGWPutLC_ObjStore_S3() {}
   ~RGWPutLC_ObjStore_S3() override {}
-  
+
  void send_response() override;
 };
 
 public:
   RGWDeleteLC_ObjStore_S3() {}
   ~RGWDeleteLC_ObjStore_S3() override {}
-  
+
  void send_response() override;
 };
 
   RGWPutCORS_ObjStore_S3() {}
   ~RGWPutCORS_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWSetRequestPayment_ObjStore_S3() {}
   ~RGWSetRequestPayment_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWInitMultipart_ObjStore_S3() {}
   ~RGWInitMultipart_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
   int prepare_encryption(map<string, bufferlist>& attrs) override;
 };
   RGWCompleteMultipart_ObjStore_S3() {}
   ~RGWCompleteMultipart_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWDeleteMultiObj_ObjStore_S3() {}
   ~RGWDeleteMultiObj_ObjStore_S3() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_status() override;
   void begin_response() override;
   void send_partial_response(rgw_obj_key& key, bool delete_marker,
 public:
   RGWPutObjRetention_ObjStore_S3() {}
   ~RGWPutObjRetention_ObjStore_S3() {}
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWConfigBucketMetaSearch_ObjStore_S3() {}
   ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   static int authorize(const DoutPrefixProvider *dpp,
                        rgw::sal::RGWRadosStore *store,
                        const rgw::auth::StrategyRegistry& auth_registry,
-                       struct req_state *s);
+                       struct req_state *s, optional_yield y);
 };
 
 class RGWHandler_Auth_S3 : public RGWHandler_REST {
   int init(rgw::sal::RGWRadosStore *store,
            struct req_state *s,
            rgw::io::BasicClient *cio) override;
-  int authorize(const DoutPrefixProvider *dpp) override {
-    return RGW_Auth_S3::authorize(dpp, store, auth_registry, s);
+  int authorize(const DoutPrefixProvider *dpp, optional_yield y) override {
+    return RGW_Auth_S3::authorize(dpp, store, auth_registry, s, y);
   }
-  int postauth_init() override { return 0; }
+  int postauth_init(optional_yield) override { return 0; }
 };
 
 class RGWHandler_REST_S3 : public RGWHandler_REST {
   int init(rgw::sal::RGWRadosStore *store,
            struct req_state *s,
            rgw::io::BasicClient *cio) override;
-  int authorize(const DoutPrefixProvider *dpp) override;
-  int postauth_init() override;
+  int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
+  int postauth_init(optional_yield y) override;
 };
 
 class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
   return (num_periods == 3);
 }
 
-static inline int valid_s3_object_name(const string& name) {
+inline int valid_s3_object_name(const string& name) {
   if (name.size() > 1024) {
     return -ERR_INVALID_OBJECT_NAME;
   }
   return 0;
 }
 
-static inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
+inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
 {
   // This function enforces Amazon's spec for bucket names.
   // (The requirements, not the recommendations.)
 
   virtual int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
 
-  virtual int get_params() override;
+  virtual int get_params(optional_yield y) override;
 
 private:
   void encode_short(char* buff, uint16_t s, int& i);
                                 const req_state* s) const = 0;
 
 public:
-  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const final;
+  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
+                       optional_yield y) const final;
 };
 
 
 
   RGWOp *op_copy() override { return NULL; }
   RGWOp *op_options() override { return NULL; }
 
-  int serve_errordoc(int http_ret, const string &errordoc_key);
+  int serve_errordoc(int http_ret, const string &errordoc_key, optional_yield y);
 public:
   using RGWHandler_REST_S3::RGWHandler_REST_S3;
   ~RGWHandler_REST_S3Website() override = default;
 
   int init(rgw::sal::RGWRadosStore *store, req_state *s, rgw::io::BasicClient* cio) override;
-  int error_handler(int err_no, string *error_content) override;
+  int error_handler(int err_no, string *error_content, optional_yield y) override;
 };
 
 class RGWHandler_REST_Service_S3Website : public RGWHandler_REST_S3Website {
   RGWGetObj_ObjStore_S3Website() : is_errordoc_request(false) {}
   explicit RGWGetObj_ObjStore_S3Website(bool is_errordoc_request) : is_errordoc_request(false) { this->is_errordoc_request = is_errordoc_request; }
   ~RGWGetObj_ObjStore_S3Website() override {}
-  int send_response_data_error() override;
+  int send_response_data_error(optional_yield y) override;
   int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
   // We override RGWGetObj_ObjStore::get_params here, to allow ignoring all
   // conditional params for error pages.
-  int get_params() override {
+  int get_params(optional_yield y) override {
       if (is_errordoc_request) {
         range_str = NULL;
         if_mod = NULL;
         if_nomatch = NULL;
         return 0;
       } else {
-        return RGWGetObj_ObjStore_S3::get_params();
+        return RGWGetObj_ObjStore_S3::get_params(y);
       }
   }
 };
 
     if (decoded.has_algorithm()) {
       auto& algorithm = decoded.get_algorithm();
       try {
-        validate_signature(dpp, decoded, algorithm, t.iss, thumbprints);
+        validate_signature(dpp, decoded, algorithm, t.iss, thumbprints, null_yield);
       } catch (...) {
         throw -EACCES;
       }
 }
 
 void
-WebTokenEngine::validate_signature(const DoutPrefixProvider* dpp, const jwt::decoded_jwt& decoded, const string& algorithm, const string& iss, const vector<string>& thumbprints) const
+WebTokenEngine::validate_signature(const DoutPrefixProvider* dpp, const jwt::decoded_jwt& decoded, const string& algorithm, const string& iss, const vector<string>& thumbprints, optional_yield y) const
 {
   if (algorithm != "HS256" && algorithm != "HS384" && algorithm != "HS512") {
     // Get certificate
     //Headers
     cert_req.append_header("Content-Type", "application/x-www-form-urlencoded");
 
-    int res = cert_req.process(null_yield);
+    int res = cert_req.process(y);
     if (res < 0) {
       ldpp_dout(dpp, 10) << "HTTP request res: " << res << dendl;
       throw -EINVAL;
 WebTokenEngine::result_t
 WebTokenEngine::authenticate( const DoutPrefixProvider* dpp,
                               const std::string& token,
-                              const req_state* const s) const
+                              const req_state* const s,
+                             optional_yield y) const
 {
   boost::optional<WebTokenEngine::token_t> t;
 
 
 } // namespace rgw::auth::sts
 
-int RGWREST_STS::verify_permission()
+int RGWREST_STS::verify_permission(optional_yield y)
 {
   STS::STSService _sts(s->cct, store, s->user->get_id(), s->auth.identity.get());
   sts = std::move(_sts);
   end_header(s);
 }
 
-int RGWSTSGetSessionToken::verify_permission()
+int RGWSTSGetSessionToken::verify_permission(optional_yield y)
 {
   rgw::Partition partition = rgw::Partition::aws;
   rgw::Service service = rgw::Service::s3;
   return 0;
 }
 
-void RGWSTSGetSessionToken::execute()
+void RGWSTSGetSessionToken::execute(optional_yield y)
 {
   if (op_ret = get_params(); op_ret < 0) {
     return;
   return 0;
 }
 
-void RGWSTSAssumeRoleWithWebIdentity::execute()
+void RGWSTSAssumeRoleWithWebIdentity::execute(optional_yield y)
 {
   if (op_ret = get_params(); op_ret < 0) {
     return;
   return 0;
 }
 
-void RGWSTSAssumeRole::execute()
+void RGWSTSAssumeRole::execute(optional_yield y)
 {
   if (op_ret = get_params(); op_ret < 0) {
     return;
 int RGW_Auth_STS::authorize(const DoutPrefixProvider *dpp,
                             rgw::sal::RGWRadosStore *store,
                             const rgw::auth::StrategyRegistry& auth_registry,
-                            struct req_state *s)
+                            struct req_state *s, optional_yield y)
 {
-    return rgw::auth::Strategy::apply(dpp, auth_registry.get_sts(), s);
+  return rgw::auth::Strategy::apply(dpp, auth_registry.get_sts(), s, y);
 }
 
 void RGWHandler_REST_STS::rgw_sts_parse_input()
   return RGWHandler_REST::init(store, s, cio);
 }
 
-int RGWHandler_REST_STS::authorize(const DoutPrefixProvider* dpp)
+int RGWHandler_REST_STS::authorize(const DoutPrefixProvider* dpp, optional_yield y)
 {
   if (s->info.args.exists("Action") && s->info.args.get("Action") == "AssumeRoleWithWebIdentity") {
-    return RGW_Auth_STS::authorize(dpp, store, auth_registry, s);
+    return RGW_Auth_STS::authorize(dpp, store, auth_registry, s, y);
   }
-  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s);
+  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s, y);
 }
 
 int RGWHandler_REST_STS::init_from_header(struct req_state* s,
 
 
 #include "rgw_auth.h"
 #include "rgw_auth_filters.h"
+#include "rgw_rest.h"
 #include "rgw_sts.h"
 #include "rgw_web_idp.h"
 #include "jwt-cpp/jwt.h"
   boost::optional<WebTokenEngine::token_t>
   get_from_jwt(const DoutPrefixProvider* dpp, const std::string& token, const req_state* const s) const;
 
-  void validate_signature (const DoutPrefixProvider* dpp, const jwt::decoded_jwt& decoded, const string& algorithm, const string& iss, const vector<string>& thumbprints) const;
+  void validate_signature (const DoutPrefixProvider* dpp, const jwt::decoded_jwt& decoded, const string& algorithm, const string& iss, const vector<string>& thumbprints, optional_yield y) const;
 
   result_t authenticate(const DoutPrefixProvider* dpp,
                         const std::string& token,
-                        const req_state* s) const;
+                        const req_state* s, optional_yield y) const;
 
 public:
   WebTokenEngine(CephContext* const cct,
     return "rgw::auth::sts::WebTokenEngine";
   }
 
-  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override {
-    return authenticate(dpp, extractor->get_token(s), s);
+  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const override {
+    return authenticate(dpp, extractor->get_token(s), s, y);
   }
 }; /* class WebTokenEngine */
 
   STS::STSService sts;
 public:
   RGWREST_STS() = default;
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   void send_response() override;
 };
 
   string iss;
 public:
   RGWSTSAssumeRoleWithWebIdentity() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "assume_role_web_identity"; }
   RGWOpType get_type() override { return RGW_STS_ASSUME_ROLE_WEB_IDENTITY; }
   string tokenCode;
 public:
   RGWSTSAssumeRole() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "assume_role"; }
   RGWOpType get_type() override { return RGW_STS_ASSUME_ROLE; }
   string tokenCode;
 public:
   RGWSTSGetSessionToken() = default;
-  void execute() override;
-  int verify_permission() override;
+  void execute(optional_yield y) override;
+  int verify_permission(optional_yield y) override;
   int get_params();
   const char* name() const override { return "get_session_token"; }
   RGWOpType get_type() override { return RGW_STS_GET_SESSION_TOKEN; }
   static int authorize(const DoutPrefixProvider *dpp,
                        rgw::sal::RGWRadosStore *store,
                        const rgw::auth::StrategyRegistry& auth_registry,
-                       struct req_state *s);
+                       struct req_state *s, optional_yield y);
 };
 
 class RGWHandler_REST_STS : public RGWHandler_REST {
   int init(rgw::sal::RGWRadosStore *store,
            struct req_state *s,
            rgw::io::BasicClient *cio) override;
-  int authorize(const DoutPrefixProvider* dpp) override;
-  int postauth_init() override { return 0; }
+  int authorize(const DoutPrefixProvider* dpp, optional_yield y) override;
+  int postauth_init(optional_yield y) override { return 0; }
 };
 
 class RGWRESTMgr_STS : public RGWRESTMgr {
 
 #define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_rgw
 
-int RGWListBuckets_ObjStore_SWIFT::get_params()
+int RGWListBuckets_ObjStore_SWIFT::get_params(optional_yield y)
 {
   prefix = s->info.args.get("prefix");
   marker = s->info.args.get("marker");
   }
 }
 
-int RGWListBucket_ObjStore_SWIFT::get_params()
+int RGWListBucket_ObjStore_SWIFT::get_params(optional_yield y)
 {
   prefix = s->info.args.get("prefix");
   marker = s->info.args.get("marker");
   dump_last_modified(s, s->bucket_mtime);
 }
 
-void RGWStatAccount_ObjStore_SWIFT::execute()
+void RGWStatAccount_ObjStore_SWIFT::execute(optional_yield y)
 {
-  RGWStatAccount_ObjStore::execute();
+  RGWStatAccount_ObjStore::execute(y);
   op_ret = store->ctl()->user->get_attrs_by_uid(s->user->get_id(), &attrs, s->yield);
 }
 
   return 0;
 }
 
-int RGWCreateBucket_ObjStore_SWIFT::get_params()
+int RGWCreateBucket_ObjStore_SWIFT::get_params(optional_yield y)
 {
   bool has_policy;
   uint32_t policy_rw_mask = 0;
   return 0;
 }
 
-int RGWPutObj_ObjStore_SWIFT::verify_permission()
+int RGWPutObj_ObjStore_SWIFT::verify_permission(optional_yield y)
 {
-  op_ret = RGWPutObj_ObjStore::verify_permission();
+  op_ret = RGWPutObj_ObjStore::verify_permission(y);
 
   /* We have to differentiate error codes depending on whether user is
    * anonymous (401 Unauthorized) or he doesn't have necessary permissions
   return 0;
 } /* RGWPutObj_ObjStore_SWIFT::update_slo_segment_sizes */
 
-int RGWPutObj_ObjStore_SWIFT::get_params()
+int RGWPutObj_ObjStore_SWIFT::get_params(optional_yield y)
 {
   if (s->has_bad_meta) {
     return -EINVAL;
     ofs = slo_info->raw_data.length();
   }
 
-  return RGWPutObj_ObjStore::get_params();
+  return RGWPutObj_ObjStore::get_params(y);
 }
 
 void RGWPutObj_ObjStore_SWIFT::send_response()
   return 0;
 }
 
-int RGWPutMetadataAccount_ObjStore_SWIFT::get_params()
+int RGWPutMetadataAccount_ObjStore_SWIFT::get_params(optional_yield y)
 {
   if (s->has_bad_meta) {
     return -EINVAL;
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-int RGWPutMetadataBucket_ObjStore_SWIFT::get_params()
+int RGWPutMetadataBucket_ObjStore_SWIFT::get_params(optional_yield y)
 {
   if (s->has_bad_meta) {
     return -EINVAL;
   rgw_flush_formatter_and_reset(s, s->formatter);
 }
 
-int RGWPutMetadataObject_ObjStore_SWIFT::get_params()
+int RGWPutMetadataObject_ObjStore_SWIFT::get_params(optional_yield y)
 {
   if (s->has_bad_meta) {
     return -EINVAL;
   formatter.close_section();
 }
 
-int RGWDeleteObj_ObjStore_SWIFT::verify_permission()
+int RGWDeleteObj_ObjStore_SWIFT::verify_permission(optional_yield y)
 {
-  op_ret = RGWDeleteObj_ObjStore::verify_permission();
+  op_ret = RGWDeleteObj_ObjStore::verify_permission(y);
 
   /* We have to differentiate error codes depending on whether user is
    * anonymous (401 Unauthorized) or he doesn't have necessary permissions
   }
 }
 
-int RGWDeleteObj_ObjStore_SWIFT::get_params()
+int RGWDeleteObj_ObjStore_SWIFT::get_params(optional_yield y)
 {
   const string& mm = s->info.args.get("multipart-manifest");
   multipart_delete = (mm.compare("delete") == 0);
 
-  return RGWDeleteObj_ObjStore::get_params();
+  return RGWDeleteObj_ObjStore::get_params(y);
 }
 
 void RGWDeleteObj_ObjStore_SWIFT::send_response()
   return 0;
 }
 
-int RGWCopyObj_ObjStore_SWIFT::get_params()
+int RGWCopyObj_ObjStore_SWIFT::get_params(optional_yield y)
 {
   if_mod = s->info.env->get("HTTP_IF_MODIFIED_SINCE");
   if_unmod = s->info.env->get("HTTP_IF_UNMODIFIED_SINCE");
   }
 }
 
-int RGWGetObj_ObjStore_SWIFT::verify_permission()
+int RGWGetObj_ObjStore_SWIFT::verify_permission(optional_yield y)
 {
-  op_ret = RGWGetObj_ObjStore::verify_permission();
+  op_ret = RGWGetObj_ObjStore::verify_permission(y);
 
   /* We have to differentiate error codes depending on whether user is
    * anonymous (401 Unauthorized) or he doesn't have necessary permissions
   }
 }
 
-int RGWGetObj_ObjStore_SWIFT::get_params()
+int RGWGetObj_ObjStore_SWIFT::get_params(optional_yield y)
 {
   const string& mm = s->info.args.get("multipart-manifest");
   skip_manifest = (mm.compare("get") == 0);
 
-  return RGWGetObj_ObjStore::get_params();
+  return RGWGetObj_ObjStore::get_params(y);
 }
 
-int RGWGetObj_ObjStore_SWIFT::send_response_data_error()
+int RGWGetObj_ObjStore_SWIFT::send_response_data_error(optional_yield y)
 {
   std::string error_content;
-  op_ret = error_handler(op_ret, &error_content);
+  op_ret = error_handler(op_ret, &error_content, y);
   if (! op_ret) {
     /* The error handler has taken care of the error. */
     return 0;
     {"tempauth", {false, RGWInfo_ObjStore_SWIFT::list_tempauth_data}},
 };
 
-void RGWInfo_ObjStore_SWIFT::execute()
+void RGWInfo_ObjStore_SWIFT::execute(optional_yield y)
 {
   bool is_admin_info_enabled = false;
 
   }
 }
 
-int RGWFormPost::get_params()
+int RGWFormPost::get_params(optional_yield y)
 {
   /* The parentt class extracts boundary info from the Content-Type. */
-  int ret = RGWPostObj_ObjStore::get_params();
+  int ret = RGWPostObj_ObjStore::get_params(y);
   if (ret < 0) {
     return ret;
   }
     return r;
   }
 
-  /* Tell RGWPostObj::execute() that it has some data to put. */
+  /* Tell RGWPostObj::execute(optional_yield y) that it has some data to put. */
   again = !boundary;
 
   return bl.length();
 }
 
 int RGWSwiftWebsiteHandler::serve_errordoc(const int http_ret,
-                                           const std::string error_doc)
+                                           const std::string error_doc,
+                                          optional_yield y)
 {
   /* Try to throw it all away. */
   s->formatter->reset();
     }
 
     int error_handler(const int err_no,
-                      std::string* const error_content) override {
+                      std::string* const error_content, optional_yield y) override {
       /* Enforce that any error generated while getting the error page will
        * not be send to a client. This allows us to recover from the double
        * fault situation by sending the original message. */
 
   RGWOp* newop = &get_errpage_op;
   RGWRequest req(0);
-  return rgw_process_authenticated(handler, newop, &req, s, true);
+  return rgw_process_authenticated(handler, newop, &req, s, y, true);
 }
 
 int RGWSwiftWebsiteHandler::error_handler(const int err_no,
-                                          std::string* const error_content)
+                                          std::string* const error_content,
+                                         optional_yield y)
 {
   if (!s->bucket.get()) {
     /* No bucket, default no-op handler */
 
   if (can_be_website_req() && ! ws_conf.error_doc.empty()) {
     set_req_state_err(s, err_no);
-    return serve_errordoc(s->err.http_ret, ws_conf.error_doc);
+    return serve_errordoc(s->err.http_ret, ws_conf.error_doc, y);
   }
 
   /* Let's go to the default, no-op handler. */
       : location(location) {
     }
 
-    int verify_permission() override {
+    int verify_permission(optional_yield) override {
       return 0;
     }
 
-    void execute() override {
+    void execute(optional_yield) override {
       op_ret = -ERR_PERMANENT_REDIRECT;
       return;
     }
   class RGWWebsiteListing : public RGWListBucket_ObjStore_SWIFT {
     const std::string prefix_override;
 
-    int get_params() override {
+    int get_params(optional_yield) override {
       prefix = prefix_override;
       max = default_max;
       delimiter = "/";
 }
 
 
-int RGWHandler_REST_SWIFT::authorize(const DoutPrefixProvider *dpp)
+int RGWHandler_REST_SWIFT::authorize(const DoutPrefixProvider *dpp, optional_yield y)
 {
-  return rgw::auth::Strategy::apply(dpp, auth_strategy, s);
+  return rgw::auth::Strategy::apply(dpp, auth_strategy, s, y);
 }
 
-int RGWHandler_REST_SWIFT::postauth_init()
+int RGWHandler_REST_SWIFT::postauth_init(optional_yield y)
 {
   struct req_init_state* t = &s->init_state;
 
 
   RGWGetObj_ObjStore_SWIFT() {}
   ~RGWGetObj_ObjStore_SWIFT() override {}
 
-  int verify_permission() override;
-  int get_params() override;
-  int send_response_data_error() override;
+  int verify_permission(optional_yield y) override;
+  int get_params(optional_yield y) override;
+  int send_response_data_error(optional_yield y) override;
   int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
 
   void set_custom_http_response(const int http_ret) {
   }
   ~RGWListBuckets_ObjStore_SWIFT() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void handle_listing_chunk(rgw::sal::RGWBucketList&& buckets) override;
   void send_response_begin(bool has_buckets) override;
   void send_response_data(rgw::sal::RGWBucketList& buckets) override;
   }
   ~RGWListBucket_ObjStore_SWIFT() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
   bool need_container_stats() override { return true; }
 };
   }
   ~RGWStatAccount_ObjStore_SWIFT() override {}
 
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
 };
 
   RGWCreateBucket_ObjStore_SWIFT() {}
   ~RGWCreateBucket_ObjStore_SWIFT() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
 
   int update_slo_segment_size(rgw_slo_entry& entry);
 
-  int verify_permission() override;
-  int get_params() override;
+  int verify_permission(optional_yield y) override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWPutMetadataAccount_ObjStore_SWIFT() {}
   ~RGWPutMetadataAccount_ObjStore_SWIFT() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWPutMetadataBucket_ObjStore_SWIFT() {}
   ~RGWPutMetadataBucket_ObjStore_SWIFT() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
 };
 
   RGWPutMetadataObject_ObjStore_SWIFT() {}
   ~RGWPutMetadataObject_ObjStore_SWIFT() override {}
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
   bool need_object_expiration() override { return true; }
 };
   RGWDeleteObj_ObjStore_SWIFT() {}
   ~RGWDeleteObj_ObjStore_SWIFT() override {}
 
-  int verify_permission() override;
-  int get_params() override;
+  int verify_permission(optional_yield y) override;
+  int get_params(optional_yield y) override;
   bool need_object_expiration() override { return true; }
   void send_response() override;
 };
   ~RGWCopyObj_ObjStore_SWIFT() override {}
 
   int init_dest_policy() override;
-  int get_params() override;
+  int get_params(optional_yield y) override;
   void send_response() override;
   void send_partial_response(off_t ofs) override;
 };
   RGWInfo_ObjStore_SWIFT() {}
   ~RGWInfo_ObjStore_SWIFT() override {}
 
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override;
   static void list_swift_data(Formatter& formatter, const ConfigProxy& config, RGWRados& store);
   static void list_tempauth_data(Formatter& formatter, const ConfigProxy& config, RGWRados& store);
             req_state* s,
             RGWHandler* dialect_handler) override;
 
-  int get_params() override;
+  int get_params(optional_yield y) override;
   int get_data(ceph::bufferlist& bl, bool& again) override;
   void send_response() override;
 
   bool is_web_dir() const;
   bool is_index_present(const std::string& index) const;
 
-  int serve_errordoc(int http_ret, std::string error_doc);
+  int serve_errordoc(int http_ret, std::string error_doc, optional_yield y);
 
   RGWOp* get_ws_redirect_op();
   RGWOp* get_ws_index_op();
   }
 
   int error_handler(const int err_no,
-                    std::string* const error_content);
+                    std::string* const error_content,
+                   optional_yield y);
   int retarget_bucket(RGWOp* op, RGWOp** new_op);
   int retarget_object(RGWOp* op, RGWOp** new_op);
 };
   int validate_bucket_name(const string& bucket);
 
   int init(rgw::sal::RGWRadosStore *store, struct req_state *s, rgw::io::BasicClient *cio) override;
-  int authorize(const DoutPrefixProvider *dpp) override;
-  int postauth_init() override;
+  int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
+  int postauth_init(optional_yield y) override;
 
   RGWAccessControlPolicy *alloc_policy() { return nullptr; /* return new RGWAccessControlPolicy_SWIFT; */ }
   void free_policy(RGWAccessControlPolicy *policy) { delete policy; }
   using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT;
   ~RGWHandler_REST_Bucket_SWIFT() override = default;
 
-  int error_handler(int err_no, std::string *error_content) override {
-    return website_handler->error_handler(err_no, error_content);
+  int error_handler(int err_no, std::string *error_content, optional_yield y) override {
+    return website_handler->error_handler(err_no, error_content, y);
   }
 
   int retarget(RGWOp* op, RGWOp** new_op) override {
   using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT;
   ~RGWHandler_REST_Obj_SWIFT() override = default;
 
-  int error_handler(int err_no, std::string *error_content) override {
-    return website_handler->error_handler(err_no, error_content);
+  int error_handler(int err_no, std::string *error_content,
+                   optional_yield y) override {
+    return website_handler->error_handler(err_no, error_content, y);
   }
 
   int retarget(RGWOp* op, RGWOp** new_op) override {
     return RGWHandler::init(store, state, cio);
   }
 
-  int authorize(const DoutPrefixProvider *dpp) override {
+  int authorize(const DoutPrefixProvider *dpp, optional_yield) override {
     return 0;
   }
 
-  int postauth_init() override {
+  int postauth_init(optional_yield) override {
     return 0;
   }
 
-  int read_permissions(RGWOp *) override {
+  int read_permissions(RGWOp *, optional_yield y) override {
     return 0;
   }
 
     return RGWHandler::init(store, state, cio);
   }
 
-  int authorize(const DoutPrefixProvider *dpp) override {
+  int authorize(const DoutPrefixProvider *dpp, optional_yield y) override {
     return 0;
   }
 
-  int postauth_init() override {
+  int postauth_init(optional_yield) override {
     return 0;
   }
 
-  int read_permissions(RGWOp *) override {
+  int read_permissions(RGWOp *, optional_yield y) override {
     return 0;
   }
 
     return RGWHandler::init(store, state, cio);
   }
 
-  int authorize(const DoutPrefixProvider *dpp) override {
+  int authorize(const DoutPrefixProvider *dpp, optional_yield) override {
     return 0;
   }
 
-  int postauth_init() override {
+  int postauth_init(optional_yield) override {
     return 0;
   }
 
-  int read_permissions(RGWOp *) override {
+  int read_permissions(RGWOp *, optional_yield y) override {
     return 0;
   }
 };
 
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("usage", RGW_CAP_READ);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "get_usage"; }
 };
 
-void RGWOp_Usage_Get::execute() {
+void RGWOp_Usage_Get::execute(optional_yield y) {
   map<std::string, bool> categories;
 
   string uid_str;
   int check_caps(const RGWUserCaps& caps) override {
     return caps.check_cap("usage", RGW_CAP_WRITE);
   }
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "trim_usage"; }
 };
 
-void RGWOp_Usage_Delete::execute() {
+void RGWOp_Usage_Delete::execute(optional_yield y) {
   string uid_str;
   string bucket_name;
   uint64_t start, end;
 
   using RGWHandler_Auth_S3::RGWHandler_Auth_S3;
   ~RGWHandler_Usage() override = default;
 
-  int read_permissions(RGWOp*) override {
+  int read_permissions(RGWOp*, optional_yield) override {
     return 0;
   }
 };
 
     return caps.check_cap("users", RGW_CAP_READ);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "list_user"; }
 };
 
-void RGWOp_User_List::execute()
+void RGWOp_User_List::execute(optional_yield y)
 {
   RGWUserAdminOpState op_state;
 
     return caps.check_cap("users", RGW_CAP_READ);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "get_user_info"; }
 };
 
-void RGWOp_User_Info::execute()
+void RGWOp_User_Info::execute(optional_yield y)
 {
   RGWUserAdminOpState op_state;
 
   op_state.set_fetch_stats(fetch_stats);
   op_state.set_sync_stats(sync_stats);
 
-  op_ret = RGWUserAdminOp_User::info(store, op_state, flusher, null_yield);
+  op_ret = RGWUserAdminOp_User::info(store, op_state, flusher, y);
 }
 
 class RGWOp_User_Create : public RGWRESTOp {
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "create_user"; }
 };
 
-void RGWOp_User_Create::execute()
+void RGWOp_User_Create::execute(optional_yield y)
 {
   std::string uid_str;
   std::string display_name;
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "modify_user"; }
 };
 
-void RGWOp_User_Modify::execute()
+void RGWOp_User_Modify::execute(optional_yield y)
 {
   std::string uid_str;
   std::string display_name;
     ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
     return;
   }
-  op_ret = RGWUserAdminOp_User::modify(store, op_state, flusher, null_yield);
+  op_ret = RGWUserAdminOp_User::modify(store, op_state, flusher, y);
 }
 
 class RGWOp_User_Remove : public RGWRESTOp {
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "remove_user"; }
 };
 
-void RGWOp_User_Remove::execute()
+void RGWOp_User_Remove::execute(optional_yield y)
 {
   std::string uid_str;
   bool purge_data;
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "create_subuser"; }
 };
 
-void RGWOp_Subuser_Create::execute()
+void RGWOp_Subuser_Create::execute(optional_yield y)
 {
   std::string uid_str;
   std::string subuser;
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "modify_subuser"; }
 };
 
-void RGWOp_Subuser_Modify::execute()
+void RGWOp_Subuser_Modify::execute(optional_yield y)
 {
   std::string uid_str;
   std::string subuser;
     ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
     return;
   }
-  op_ret = RGWUserAdminOp_Subuser::modify(store, op_state, flusher, null_yield);
+  op_ret = RGWUserAdminOp_Subuser::modify(store, op_state, flusher, y);
 }
 
 class RGWOp_Subuser_Remove : public RGWRESTOp {
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "remove_subuser"; }
 };
 
-void RGWOp_Subuser_Remove::execute()
+void RGWOp_Subuser_Remove::execute(optional_yield y)
 {
   std::string uid_str;
   std::string subuser;
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "create_access_key"; }
 };
 
-void RGWOp_Key_Create::execute()
+void RGWOp_Key_Create::execute(optional_yield y)
 {
   std::string uid_str;
   std::string subuser;
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "remove_access_key"; }
 };
 
-void RGWOp_Key_Remove::execute()
+void RGWOp_Key_Remove::execute(optional_yield y)
 {
   std::string uid_str;
   std::string subuser;
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "add_user_caps"; }
 };
 
-void RGWOp_Caps_Add::execute()
+void RGWOp_Caps_Add::execute(optional_yield y)
 {
   std::string uid_str;
   std::string caps;
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "remove_user_caps"; }
 };
 
-void RGWOp_Caps_Remove::execute()
+void RGWOp_Caps_Remove::execute(optional_yield y)
 {
   std::string uid_str;
   std::string caps;
     return caps.check_cap("users", RGW_CAP_READ);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "get_quota_info"; }
 };
 
 
-void RGWOp_Quota_Info::execute()
+void RGWOp_Quota_Info::execute(optional_yield y)
 {
   RGWUserAdminOpState op_state;
 
     return caps.check_cap("users", RGW_CAP_WRITE);
   }
 
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "set_quota_info"; }
 };
  *
  */
 
-void RGWOp_Quota_Set::execute()
+void RGWOp_Quota_Set::execute(optional_yield y)
 {
   RGWUserAdminOpState op_state;
 
   }
 
   string err;
-  op_ret = user.modify(op_state, null_yield, &err);
+  op_ret = user.modify(op_state, y, &err);
   if (op_ret < 0) {
     ldout(store->ctx(), 20) << "failed updating user info: " << op_ret << ": " << err << dendl;
     return;
 
   using RGWHandler_Auth_S3::RGWHandler_Auth_S3;
   ~RGWHandler_User() override = default;
 
-  int read_permissions(RGWOp*) override {
+  int read_permissions(RGWOp*, optional_yield) override {
     return 0;
   }
 };
 
   end_header(s);
 }
 
-int RGWRestUserPolicy::verify_permission()
+int RGWRestUserPolicy::verify_permission(optional_yield y)
 {
   if (s->auth.identity->is_anonymous()) {
     return -EACCES;
   return 0;
 }
 
-void RGWPutUserPolicy::execute()
+void RGWPutUserPolicy::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWGetUserPolicy::execute()
+void RGWGetUserPolicy::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWListUserPolicies::execute()
+void RGWListUserPolicies::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
   return 0;
 }
 
-void RGWDeleteUserPolicy::execute()
+void RGWDeleteUserPolicy::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0) {
 
 // vim: ts=8 sw=2 smarttab ft=cpp
 
 #pragma once
+#include "rgw_rest.h"
 
 class RGWRestUserPolicy : public RGWRESTOp {
 protected:
   bool validate_input();
 
 public:
-  int verify_permission() override;
+  int verify_permission(optional_yield y) override;
   virtual uint64_t get_op() = 0;
   void send_response() override;
   void dump(Formatter *f) const;
 class RGWPutUserPolicy : public RGWUserPolicyWrite {
 public:
   RGWPutUserPolicy() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "put_user-policy"; }
   uint64_t get_op() override;
 class RGWGetUserPolicy : public RGWUserPolicyRead {
 public:
   RGWGetUserPolicy() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "get_user_policy"; }
   uint64_t get_op() override;
 class RGWListUserPolicies : public RGWUserPolicyRead {
 public:
   RGWListUserPolicies() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "list_user_policies"; }
   uint64_t get_op() override;
 class RGWDeleteUserPolicy : public RGWUserPolicyWrite {
 public:
   RGWDeleteUserPolicy() = default;
-  void execute() override;
+  void execute(optional_yield y) override;
   int get_params();
   const char* name() const override { return "delete_user_policy"; }
   uint64_t get_op() override;
 
 
 #include <string>
 
+#include "common/ceph_json.h"
 #include "common/ceph_context.h"
 
 class RGWCtl;
 
 }
 
 void TempURLEngine::get_owner_info(const DoutPrefixProvider* dpp, const req_state* const s,
-                                   RGWUserInfo& owner_info) const
+                                   RGWUserInfo& owner_info, optional_yield y) const
 {
   /* We cannot use req_state::bucket_name because it isn't available
    * now. It will be initialized in RGWHandler_REST_SWIFT::postauth_init(). */
   /* Need to get user info of bucket owner. */
   RGWBucketInfo bucket_info;
   RGWSI_MetaBackend_CtxParams bectx_params = RGWSI_MetaBackend_CtxParams_SObj(s->sysobj_ctx);
-  int ret = ctl->bucket->read_bucket_info(b, &bucket_info, null_yield, RGWBucketCtl::BucketInstance::GetParams()
-                                                                       .set_bectx_params(bectx_params));
+  int ret = ctl->bucket->read_bucket_info(b, &bucket_info, y, RGWBucketCtl::BucketInstance::GetParams().set_bectx_params(bectx_params));
   if (ret < 0) {
     throw ret;
   }
 }; /* TempURLEngine::PrefixableSignatureHelper */
 
 TempURLEngine::result_t
-TempURLEngine::authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const
+TempURLEngine::authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const
 {
   if (! is_applicable(s)) {
     return result_t::deny();
 
   RGWUserInfo owner_info;
   try {
-    get_owner_info(dpp, s, owner_info);
+    get_owner_info(dpp, s, owner_info, y);
   } catch (...) {
     ldpp_dout(dpp, 5) << "cannot get user_info of account's owner" << dendl;
     return result_t::reject();
 ExternalTokenEngine::result_t
 ExternalTokenEngine::authenticate(const DoutPrefixProvider* dpp,
                                   const std::string& token,
-                                  const req_state* const s) const
+                                  const req_state* const s, optional_yield y) const
 {
   if (! is_applicable(token)) {
     return result_t::deny();
 
   ldpp_dout(dpp, 10) << "rgw_swift_validate_token url=" << url_buf << dendl;
 
-  int ret = validator.process(null_yield);
+  int ret = validator.process(y);
   if (ret < 0) {
     throw ret;
   }
 } /* namespace rgw */
 
 
-void RGW_SWIFT_Auth_Get::execute()
+void RGW_SWIFT_Auth_Get::execute(optional_yield y)
 {
   int ret = -EPERM;
 
   return RGWHandler::init(store, state, cio);
 }
 
-int RGWHandler_SWIFT_Auth::authorize(const DoutPrefixProvider *dpp)
+int RGWHandler_SWIFT_Auth::authorize(const DoutPrefixProvider *dpp, optional_yield)
 {
   return 0;
 }
 
   /* Helper methods. */
   void get_owner_info(const DoutPrefixProvider* dpp, 
                       const req_state* s,
-                      RGWUserInfo& owner_info) const;
+                      RGWUserInfo& owner_info,
+                     optional_yield y) const;
   std::string convert_from_iso8601(std::string expires) const;
   bool is_applicable(const req_state* s) const noexcept;
   bool is_expired(const std::string& expires) const;
     return "rgw::auth::swift::TempURLEngine";
   }
 
-  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override;
+  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const override;
 };
 
 
   const rgw::auth::LocalApplier::Factory* const apl_factory;
 
   bool is_applicable(const std::string& token) const noexcept;
+  using rgw::auth::Engine::authenticate;
   result_t authenticate(const DoutPrefixProvider* dpp,
                         const std::string& token,
                         const req_state* s) const;
     return "rgw::auth::swift::SignedTokenEngine";
   }
 
-  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override {
+  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
+                       optional_yield y) const override {
     return authenticate(dpp, extractor->get_token(s), s);
   }
 };
   bool is_applicable(const std::string& token) const noexcept;
   result_t authenticate(const DoutPrefixProvider* dpp,
                         const std::string& token,
-                        const req_state* s) const;
+                        const req_state* s, optional_yield y) const;
 
 public:
   ExternalTokenEngine(CephContext* const cct,
     return "rgw::auth::swift::ExternalTokenEngine";
   }
 
-  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override {
-    return authenticate(dpp, extractor->get_token(s), s);
+  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
+                       optional_yield y) const override {
+    return authenticate(dpp, extractor->get_token(s), s, y);
   }
 };
 
   RGW_SWIFT_Auth_Get() {}
   ~RGW_SWIFT_Auth_Get() override {}
 
-  int verify_permission() override { return 0; }
-  void execute() override;
+  int verify_permission(optional_yield) override { return 0; }
+  void execute(optional_yield y) override;
   const char* name() const override { return "swift_auth_get"; }
   dmc::client_id dmclock_client() override { return dmc::client_id::auth; }
 };
   RGWOp *op_get() override;
 
   int init(rgw::sal::RGWRadosStore *store, struct req_state *state, rgw::io::BasicClient *cio) override;
-  int authorize(const DoutPrefixProvider *dpp) override;
-  int postauth_init() override { return 0; }
-  int read_permissions(RGWOp *op) override { return 0; }
+  int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
+  int postauth_init(optional_yield) override { return 0; }
+  int read_permissions(RGWOp *op, optional_yield) override { return 0; }
 
   virtual RGWAccessControlPolicy *alloc_policy() { return NULL; }
   virtual void free_policy(RGWAccessControlPolicy *policy) {}
 
     es_module = static_cast<RGWElasticSyncModuleInstance *>(sync_module_ref.get());
   }
 
-  int verify_permission() override {
+  int verify_permission(optional_yield) override {
     return 0;
   }
   virtual int get_params() = 0;
   void pre_exec() override;
-  void execute() override;
+  void execute(optional_yield y) override;
 
   const char* name() const override { return "metadata_search"; }
   virtual RGWOpType get_type() override { return RGW_OP_METADATA_SEARCH; }
   rgw_bucket_object_pre_exec(s);
 }
 
-void RGWMetadataSearchOp::execute()
+void RGWMetadataSearchOp::execute(optional_yield y)
 {
   op_ret = get_params();
   if (op_ret < 0)
   ldout(s->cct, 20) << "sending request to elasticsearch, payload=" << string(in.c_str(), in.length()) << dendl;
   auto& extra_headers = es_module->get_request_headers();
   op_ret = conn->get_resource(resource, ¶ms, &extra_headers,
-                              out, &in, nullptr, null_yield);
+                              out, &in, nullptr, y);
   if (op_ret < 0) {
     ldout(s->cct, 0) << "ERROR: failed to fetch resource (r=" << resource << ", ret=" << op_ret << ")" << dendl;
     return;
 
 // ceph specifc topics handler factory
 class RGWHandler_REST_PSTopic : public RGWHandler_REST_S3 {
 protected:
-  int init_permissions(RGWOp* op) override {
+  int init_permissions(RGWOp* op, optional_yield) override {
     return 0;
   }
 
-  int read_permissions(RGWOp* op) override {
+  int read_permissions(RGWOp* op, optional_yield) override {
     return 0;
   }
 
 // subscriptions handler factory
 class RGWHandler_REST_PSSub : public RGWHandler_REST_S3 {
 protected:
-  int init_permissions(RGWOp* op) override {
+  int init_permissions(RGWOp* op, optional_yield) override {
     return 0;
   }
 
-  int read_permissions(RGWOp* op) override {
+  int read_permissions(RGWOp* op, optional_yield) override {
     return 0;
   }
   bool supports_quota() override {
 
 public:
   const char* name() const override { return "pubsub_notification_create"; }
-  void execute() override;
+  void execute(optional_yield y) override;
 };
 
-void RGWPSCreateNotif_ObjStore::execute()
+void RGWPSCreateNotif_ObjStore::execute(optional_yield y)
 {
   ups.emplace(store, s->owner.get_id());
 
   }
 
 public:
-  void execute() override;
+  void execute(optional_yield y) override;
   const char* name() const override { return "pubsub_notification_delete"; }
 };
 
-void RGWPSDeleteNotif_ObjStore::execute() {
+void RGWPSDeleteNotif_ObjStore::execute(optional_yield y) {
   op_ret = get_params();
   if (op_ret < 0) {
     return;
   }
 
 public:
-  void execute() override;
+  void execute(optional_yield y) override;
   void send_response() override {
     if (op_ret) {
       set_req_state_err(s, op_ret);
   const char* name() const override { return "pubsub_notifications_list"; }
 };
 
-void RGWPSListNotifs_ObjStore::execute()
+void RGWPSListNotifs_ObjStore::execute(optional_yield y)
 {
   ups.emplace(store, s->owner.get_id());
   auto b = ups->get_bucket(bucket_info.bucket);
 // ceph specific notification handler factory
 class RGWHandler_REST_PSNotifs : public RGWHandler_REST_S3 {
 protected:
-  int init_permissions(RGWOp* op) override {
+  int init_permissions(RGWOp* op, optional_yield) override {
     return 0;
   }
 
-  int read_permissions(RGWOp* op) override {
+  int read_permissions(RGWOp* op, optional_yield) override {
     return 0;
   }
   bool supports_quota() override {