]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: more refactoring work
authorYehuda Sadeh <yehuda@redhat.com>
Thu, 25 Apr 2019 23:32:44 +0000 (16:32 -0700)
committerCasey Bodley <cbodley@redhat.com>
Mon, 29 Jul 2019 19:20:47 +0000 (15:20 -0400)
notable changes are around user metadata. Create an api that uses
the service interface (that requires backend context) and use it
for higher level functions. Still a lot to do.

Following rebase, started modifying the internal meta apis to deal
with optional_yield param. Passing it from top level metadata handlers
and from ctls, all the way down to the services. However, since following
commit will introduce many more changes, this was only done for the
user apis.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
17 files changed:
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h
src/rgw/rgw_common.h
src/rgw/rgw_metadata.cc
src/rgw/rgw_metadata.h
src/rgw/rgw_otp.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_role.cc
src/rgw/rgw_sync.cc
src/rgw/rgw_user.cc
src/rgw/rgw_user.h
src/rgw/services/svc_bucket.h
src/rgw/services/svc_meta_be.h
src/rgw/services/svc_meta_be_sobj.cc
src/rgw/services/svc_meta_be_sobj.h
src/rgw/services/svc_user.cc
src/rgw/services/svc_user.h

index 283b254964628ea268c032295cefd60dc668f2f2..b9ccd60413163d893e955f2de62b6a0a92d5c3d7 100644 (file)
@@ -31,6 +31,7 @@
 #include "services/svc_bucket.h"
 #include "services/svc_meta.h"
 #include "services/svc_meta_be_sobj.h"
+#include "services/svc_user.h"
 
 #include "include/rados/librados.hpp"
 // until everything is moved from rgw_common
@@ -48,8 +49,7 @@
 // define as static when RGWBucket implementation completes
 void rgw_get_buckets_obj(const rgw_user& user_id, string& buckets_obj_id)
 {
-  buckets_obj_id = user_id.to_str();
-  buckets_obj_id += RGW_BUCKETS_OBJ_SUFFIX;
+  buckets_obj_id = RGWSI_User::get_buckets_oid(user_id);
 }
 
 /*
@@ -1849,7 +1849,7 @@ static int process_stale_instances(RGWRados *store, RGWBucketAdminOpState& op_st
   do {
     list<std::string> keys;
 
-    ret = store->svc.meta->get_mgr()meta_mgr->list_keys_next(handle, default_max_keys, keys, &truncated);
+    ret = store->svc.meta->get_mgr()->list_keys_next(handle, default_max_keys, keys, &truncated);
     if (ret < 0 && ret != -ENOENT) {
       cerr << "ERROR: lists_keys_next(): " << cpp_strerror(-ret) << std::endl;
       return ret;
@@ -2553,10 +2553,6 @@ public:
     return 0;
   }
 
-  RGWSI_MetaBackend::Type required_be_type() override {
-    return MDBE_SOBJ;
-  }
-
   int read_bucket_entrypoint_info(RGWSI_MetaBackend::Context *ctx,
                                   string& entry,
                                   RGWBucketEntryPoint *be,
@@ -2568,7 +2564,7 @@ public:
     RGWSI_MBSObj_GetParams params = {
       .pmtime = pmtime,
       .pattrs = pattrs,
-      .pbl = &bl;
+      .pbl = &bl,
     };
     int ret = meta_be->get_entry(ctx, params,
                                  objv_tracker);
@@ -2762,6 +2758,10 @@ public:
   }
   ~RGWMetadataHandlerPut_Bucket() {}
 
+  void encode_obj(bufferlist *bl) override {
+    ceph::encode(obj->get_be(), *bl);
+  }
+
   int put_checked(RGWMetadataObject *_old_obj) override;
   int put_post() override;
 };
@@ -2779,16 +2779,9 @@ int RGWMetadataHandlerPut_Bucket::put_checked(RGWMetadataObject *_old_obj)
 {
   RGWBucketEntryMetadataObject *old_obj = static_cast<RGWBucketEntryMetadataObject *>(_old_obj);
 
-  auto& be = obj->get_be();
-
-  map<string, bufferlist> *pattrs = (old_obj ? &old_obj->get_attrs() : nullptr);
+  obj->set_pattrs(old_obj->get_attrs());
 
-  ret = handler->store_bucket_entrypoint_info(entry, be, false, objv_tracker,
-                                              obj->get_mtime(), &old_obj->get_attrs());
-  if (ret < 0)
-    return ret;
-
-  return 0;
+  return RGWMetadataHandlerPut_SObj::put_checked(old_obj);
 }
 
 int RGWMetadataHandlerPut_Bucket::put_post()
@@ -3059,19 +3052,13 @@ pubic:
 
 class RGWBucketInstanceMetadataHandler : public RGWMetadataHandler {
   int read_bucket_instance_entry(RGWSI_MetaBackend::Context *ctx,
-                                 string& entry,
                                  RGWBucketCompleteInfo *bi,
                                  ceph::real_time *pmtime,
-                                 map<string, bufferlist> *pattrs,
                                  optional_yield y) {
     RGWObjVersionTracker objv_tracker,
     bufferlist bl;
-    RGWSI_MBSObj_GetParams params = {
-      .pmtime = pmtime,
-      .pattrs = pattrs,
-      .pbl = &bl;
-      .y = y;
-    };
+    RGWSI_MBSObj_GetParams params(&bl, &bi.attrs, pmtime, y);
+
     int ret = meta_be->get_entry(ctx, params,
                                  &objv_tracker);
     if (ret < 0) {
@@ -3090,33 +3077,13 @@ class RGWBucketInstanceMetadataHandler : public RGWMetadataHandler {
     return 0;
   }
 
-  int store_bucket_instance_entry(RGWSI_MetaBackend::Context *ctx,
-                                  string& entry,
-                                  const RGWBucketInfo& bi,
-                                  RGWObjVersionTracker *objv_tracker,
-                                  const ceph::real_time& mtime,
-                                  map<string, bufferlist> *pattrs) {
-    RGWSI_MBSObj_PutParams params = {
-      .mtime = mtime,
-      .pattrs = pattrs,
-    };
-    ceph::encode(be, params.bl);
-    int ret = meta_be->put_entry(ctx, params,
-                                 objv_tracker);
-    if (ret < 0) {
-      return ret;
-    }
-
-    return 0;
-  }
-
   int remove_bucket_instance_entry(RGWSI_MetaBackend::Context *ctx,
                                    string& entry,
                                    RGWObjVersionTracker *objv_tracker,
                                    const ceph::real_time& mtime) {
-    RGWSI_MBSObj_RemoveParams params = {
-      .mtime = mtime,
-    };
+    RGWSI_MBSObj_RemoveParams params;
+    params.mtime = mtime,
+
     int ret = meta_be->do_remove(ctx, params,
                                  objv_tracker);
     if (ret < 0) {
@@ -3132,11 +3099,9 @@ public:
 
   int do_get(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject **obj) override {
     RGWBucketCompleteInfo bci;
-
     real_time mtime;
-    map<string, bufferlist> attrs;
 
-    int ret = read_bucket_instance_entry(ctx, entry, &bci, &mtime, &attrs, null_yield);
+    int ret = read_bucket_instance_entry(ctx, &bci, &mtime, null_yield);
     if (ret < 0)
       return ret;
 
@@ -3159,7 +3124,7 @@ public:
   int do_remove(RGWSI_MetaBackend::Context *ctx, string& entry, RGWObjVersionTracker& objv_tracker) override {
     RGWBucketCompleteInfo bci;
 
-    int ret = read_bucket_instance_entry(ctx, entry, bci, nullptr, nullptr, null_yield);
+    int ret = read_bucket_instance_entry(ctx, entry, bci, nullptr, null_yield);
     if (ret < 0 && ret != -ENOENT)
       return ret;
 
@@ -3240,10 +3205,16 @@ public:
                                        RGWMDLogSyncType type) : RGWMetadataHanderPut_SObj(ctx, entry, obj, objv_tracker, type),
                                                                 handler(_handler) {
     obj = static_cast<RGWBucketInstanceMetadataObject *>(_obj);
+
+    auto& bci = obj->get_bci();
+    obj->set_pattrs(&bci.attrs);
+  }
+
+  void encode_obj(bufferlist *bl) override {
+    ceph::encode(obj->get_bucket_info(), *bl);
   }
 
   int put_pre() override;
-  int put_checked(RGWMetadataObject *_old_obj) override;
   int put_post() override;
 };
 
@@ -3259,6 +3230,8 @@ int RGWBucketInstanceMetadatHandler::do_put(RGWSI_MetaBackend::Context *ctx, str
 
 int RGWMetadataHandlerPut_BucketInstance::put_pre()
 {
+  RGWBucketCompleteInfo& bci = obj->get_bci();
+
   RGWBucketInstanceMetadataObject *old_obj = static_cast<RGWBucketInstanceMetadataObject *>(_old_obj);
 
   RGWBucketCompleteInfo *old_bci = (old_obj ? &old_obj->get_bci() : nullptr);
@@ -3324,14 +3297,6 @@ int RGWMetadataHandlerPut_BucketInstance::put_pre()
   return 0;
 }
 
-int RGWMetadataHandlerPut_BucketInstance::put_checked(RGWMetadataObject *_old_obj) {
-  ret = store_bucket_instance_entry(bci.info, false, mtime, &bci.attrs);
-  if (ret < 0)
-    return ret;
-
-  return 0;
-}
-
 int RGWMetadataHandlerPut_BucketInstance::put_post()
 {
   objv_tracker = bci.info.objv_tracker;
index 75b2476abc8bbc0e1c5cd99a7f276074013e300c..2508954b9f8399909c556a0f3d63db60b28210c8 100644 (file)
@@ -72,6 +72,7 @@ public:
     ep(_ep), attrs(std::move(_attrs)) {
     objv = v;
     mtime = m;
+    set_pattrs (&attrs);
   }
 
   void dump(Formatter *f) const override {
index 79a6b2dd930f3fd58f9c4fb22aaf0e1508ba030f..9617f772c2a2669259e9d63cdfe0a1d9f0288992 100644 (file)
@@ -130,8 +130,6 @@ using ceph::crypto::MD5;
 #define RGW_ATTR_CRYPT_KEYID    RGW_ATTR_CRYPT_PREFIX "keyid"
 #define RGW_ATTR_CRYPT_KEYSEL   RGW_ATTR_CRYPT_PREFIX "keysel"
 
-#define RGW_BUCKETS_OBJ_SUFFIX ".buckets"
-
 #define RGW_FORMAT_PLAIN        0
 #define RGW_FORMAT_XML          1
 #define RGW_FORMAT_JSON         2
index 7ce1f042276bcf70d6edda21fd6e6b617d7d1d09..16c8ca88504ae83c1b8bb73d2060fa2f91a42e9f 100644 (file)
@@ -304,10 +304,6 @@ public:
 
   string get_type() override { return string(); }
 
-  RGWSI_MetaBackend::Type required_be_type() override {
-    return RGWSI_MetaBackend::Type::MDBE_SOBJ; /* handled doesn't really using the backend */
-  }
-
   int init_module() override {
     be_module.reset(new HandlerModule());
     return 0;
@@ -317,10 +313,10 @@ public:
     return new RGWMetadataObject;
   }
 
-  int do_get(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject **obj) override { return -ENOTSUP; }
+  int do_get(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject **obj, optional_yield y) override { return -ENOTSUP; }
   int do_put(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject *obj,
-             RGWObjVersionTracker& objv_tracker, RGWMDLogSyncType type) override { return -ENOTSUP; }
-  int do_remove(RGWSI_MetaBackend::Context *ctx, string& entry, RGWObjVersionTracker& objv_tracker) override { return -ENOTSUP; }
+             RGWObjVersionTracker& objv_tracker, optional_yield y, RGWMDLogSyncType type) override { return -ENOTSUP; }
+  int do_remove(RGWSI_MetaBackend::Context *ctx, string& entry, RGWObjVersionTracker& objv_tracker, optional_yield y) override { return -ENOTSUP; }
 
   int list_keys_init(const string& marker, void **phandle) override {
     iter_data *data = new iter_data;
@@ -389,6 +385,18 @@ int RGWMetadataHandler::init(RGWMetadataManager *manager)
   return manager->register_handler(this, &meta_be, &be_handle);
 }
 
+RGWMetadataHandler::Put::Put(RGWMetadataHandler *handler, RGWSI_MetaBackend::Context *_ctx,
+                             string& _entry, RGWMetadataObject *_obj,
+                             RGWObjVersionTracker& _objv_tracker,
+                             optional_yield _y,
+                             RGWMDLogSyncType _type) :
+  ctx(_ctx), entry(_entry),
+  obj(_obj), objv_tracker(_objv_tracker),
+  apply_type(_type), y(_y)
+{
+  meta_be = handler->get_meta_be();
+}
+
 int RGWMetadataHandlerPut_SObj::put()
 {
   RGWMetadataObject *old_obj{nullptr};
@@ -401,8 +409,8 @@ int RGWMetadataHandlerPut_SObj::put()
 
   std::unique_ptr<RGWMetadataObject> oo(old_obj);
 
-  auto old_ver = (!old_obj ? : old_obj->get_version());
-  auto old_mtime = (!old_obj ? : old_obj->get_mtime());
+  auto old_ver = (!old_obj ? obj_version() : old_obj->get_version());
+  auto old_mtime = (!old_obj ? ceph::real_time() : old_obj->get_mtime());
 
   // are we actually going to perform this put, or is it too old?
   bool exists = (ret != -ENOENT);
@@ -412,20 +420,19 @@ int RGWMetadataHandlerPut_SObj::put()
     return STATUS_NO_APPLY;
   }
 
-  objv_tracker.read_version = old_ver.read_version; /* maintain the obj version we just read */
+  objv_tracker.read_version = old_ver; /* maintain the obj version we just read */
 
   return put_checked(old_obj);
 }
 
 int RGWMetadataHandlerPut_SObj::put_checked(RGWMetadataObject *_old_obj)
 {
-  RGWSI_MBSObj_PutParams params = {
-    .mtime = obj->mtime,
-    .pattrs = obj->pattrs,
-  };
-  ceph::encode(be, params.bl);
+  RGWSI_MBSObj_PutParams params(obj->get_pattrs(), obj->get_mtime());
+
+  encode_obj(&params.bl);
   int ret = meta_be->put_entry(ctx, params,
-                               objv_tracker);
+                               &objv_tracker,
+                               y);
   if (ret < 0) {
     return ret;
   }
@@ -446,33 +453,48 @@ int RGWMetadataHandler::do_put_operate(Put *put_op)
   }
 
   r = put_op->put_post();
-  if (r != 0) }  /* e.g., -error or STATUS_APPLIED */
+  if (r != 0) {  /* e.g., -error or STATUS_APPLIED */
     return r;
   }
 
   return 0;
 }
-}
 
-int RGWMetadataHandler::get(string& entry, RGWMetadataObject **obj)
+int RGWMetadataHandler::call_with_ctx(std::function<int(RGWSI_MetaBackend::Context *ctx)> f)
 {
   RGWSI_Meta_Ctx ctx;
-  init_ctx(be_handle, entry, nullptr, &ctx);
-  return do_get(ctx.get(), entry, obj);
+  meta_be->init_ctx(be_handle, &ctx);
+  return f(ctx.get());
 }
 
-int RGWMetadataHandler::put(string& entry, RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker, RGWMDLogSyncType type)
+int RGWMetadataHandler::call_with_ctx(const string& entry, std::function<int(RGWSI_MetaBackend::Context *ctx)> f)
 {
   RGWSI_Meta_Ctx ctx;
-  init_ctx(be_handle, entry, obj, &ctx);
-  return do_put(ctx.get(), entry, obj, objv_tracker, type);
+  meta_be->init_ctx(be_handle, &ctx);
+  ctx->set_key(entry);
+  return f(ctx.get());
 }
 
-int RGWMetadataHandler::remove(string& entry, RGWObjVersionTracker& objv_tracker)
+int RGWMetadataHandler::get(string& entry, RGWMetadataObject **obj, optional_yield y)
 {
-  RGWSI_Meta_Ctx ctx;
-  init_ctx(be_handle, entry, nullptr, &ctx);
-  return do_remove(ctx.get(), entry, objv_tracker);
+  return call_with_ctx(entry, [&](RGWSI_MetaBackend::Context *ctx) {
+    return do_get(ctx, entry, obj, y);
+  });
+}
+
+int RGWMetadataHandler::put(string& entry, RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
+                            optional_yield y, RGWMDLogSyncType type)
+{
+  return call_with_ctx(entry, [&](RGWSI_MetaBackend::Context *ctx) {
+    return do_put(ctx, entry, obj, objv_tracker, y, type);
+  });
+}
+
+int RGWMetadataHandler::remove(string& entry, RGWObjVersionTracker& objv_tracker, optional_yield y)
+{
+  return call_with_ctx(entry, [&](RGWSI_MetaBackend::Context *ctx) {
+    return do_remove(ctx, entry, objv_tracker, y);
+  });
 }
 
 int RGWMetadataManager::register_handler(RGWMetadataHandler *handler, RGWSI_MetaBackend **pmeta_be, RGWSI_MetaBackend_Handle *phandle)
index ba72aced593884381c7c401189b3bf2b4adb1ca7..80ed6c445161ee2bd6f30c7c447c6ad7a60c45f8 100644 (file)
@@ -33,12 +33,19 @@ class RGWMetadataObject {
 protected:
   obj_version objv;
   ceph::real_time mtime;
+  std::map<string, bufferlist> *pattrs{nullptr};
   
 public:
   RGWMetadataObject() {}
   virtual ~RGWMetadataObject() {}
   obj_version& get_version();
   real_time get_mtime() { return mtime; }
+  void set_pattrs(std::map<string, bufferlist> *_pattrs) {
+    pattrs = _pattrs;
+  }
+  std::map<string, bufferlist> *get_pattrs() {
+    return pattrs;
+  }
 
   virtual void dump(Formatter *f) const {}
 };
@@ -53,22 +60,24 @@ class RGWMetadataHandler {
 public:
   class Put {
   protected:
+    RGWSI_MetaBackend *meta_be;
     RGWMetadataHandler *handler;
     RGWSI_MetaBackend::Context *ctx;
     string& entry;
     RGWMetadataObject *obj;
     RGWObjVersionTracker& objv_tracker;
     RGWMDLogSyncType apply_type;
+    optional_yield y;
 
     int get(RGWMetadataObject **obj) {
-      return handler->do_get(ctx, entry, obj);
+      return handler->do_get(ctx, entry, obj, y);
     }
   public:
     Put(RGWMetadataHandler *handler, RGWSI_MetaBackend::Context *_ctx,
         string& _entry, RGWMetadataObject *_obj,
-        RGWObjVersionTracker& _objv_tracker, RGWMDLogSyncType _type) : ctx(_ctx), entry(_entry),
-                                                                       obj(_obj), objv_tracker(_objv_tracker),
-                                                                       apply_type(_type) {}
+        RGWObjVersionTracker& _objv_tracker, optional_yield _y,
+        RGWMDLogSyncType _type);
+
     virtual ~Put() {}
 
     virtual int put_pre() {
@@ -90,11 +99,14 @@ protected:
   RGWSI_MetaBackend_Handle be_handle{0};
   RGWSI_MetaBackend::ModuleRef be_module;
 
-  virtual int do_get(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject **obj) = 0;
+  virtual int do_get(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject **obj,
+                     optional_yield y) = 0;
   virtual int do_put(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject *obj,
-                     RGWObjVersionTracker& objv_tracker, RGWMDLogSyncType type) = 0;
+                     RGWObjVersionTracker& objv_tracker, RGWMDLogSyncType type,
+                     optional_yield y) = 0;
   virtual int do_put_operate(Put *put_op);
-  virtual int do_remove(RGWSI_MetaBackend::Context *ctx, string& entry, RGWObjVersionTracker& objv_tracker) = 0;
+  virtual int do_remove(RGWSI_MetaBackend::Context *ctx, string& entry, RGWObjVersionTracker& objv_tracker,
+                        optional_yield y) = 0;
 
   virtual int init_module() = 0;
 
@@ -102,16 +114,19 @@ public:
   virtual ~RGWMetadataHandler() {}
   virtual string get_type() = 0;
 
-  virtual RGWSI_MetaBackend::Type required_be_type() = 0;
   virtual RGWSI_MetaBackend::ModuleRef& get_be_module() {
     return be_module;
   }
 
+  RGWSI_MetaBackend  *get_meta_be() {
+    return meta_be;
+  }
+
   virtual RGWMetadataObject *get_meta_obj(JSONObj *jo, const obj_version& objv, const ceph::real_time& mtime) = 0;
 
-  int get(string& entry, RGWMetadataObject **obj);
-  int put(string& entry, RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker, RGWMDLogSyncType type);
-  int remove(string& entry, RGWObjVersionTracker& objv_tracker);
+  int get(string& entry, RGWMetadataObject **obj, optional_yield y);
+  int put(string& entry, RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker, optional_yield y, RGWMDLogSyncType type);
+  int remove(string& entry, RGWObjVersionTracker& objv_tracker, optional_yield y);
 
   virtual int list_keys_init(const string& marker, void **phandle) = 0;
   virtual int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) = 0;
@@ -121,8 +136,6 @@ public:
 
   int init(RGWMetadataManager *manager);
 
-
-protected:
   /**
    * Compare an incoming versus on-disk tag/version+mtime combo against
    * the sync mode to see if the new one should replace the on-disk one.
@@ -152,6 +165,10 @@ protected:
     }
     return true;
   }
+
+  int call_with_ctx(std::function<int(RGWSI_MetaBackend::Context *ctx)> f);
+  int call_with_ctx(const string& entry, std::function<int(RGWSI_MetaBackend::Context *ctx)> f);
+
 };
 
 class RGWMetadataTopHandler;
@@ -167,17 +184,19 @@ class RGWMetadataManager {
   int find_handler(const string& metadata_key, RGWMetadataHandler **handler, string& entry);
   int register_handler(RGWMetadataHandler *handler, RGWSI_MetaBackend **pmeta_be, RGWSI_MetaBackend_Handle *phandle);
 
+protected:
+  int call_with_ctx(const string& entry, RGWMetadataObject *obj, std::function<int(RGWSI_MetaBackend::Context *ctx)> f);
 public:
   RGWMetadataManager(RGWSI_Meta *_meta_svc);
   ~RGWMetadataManager();
 
   RGWMetadataHandler *get_handler(const string& type);
 
-  int get(string& metadata_key, Formatter *f);
-  int put(string& metadata_key, bufferlist& bl,
+  int get(string& metadata_key, Formatter *f, optional_yield y);
+  int put(string& metadata_key, bufferlist& bl, optional_yield y,
           RGWMDLogSyncType sync_mode,
           obj_version *existing_version = NULL);
-  int remove(string& metadata_key);
+  int remove(string& metadata_key, optional_yield y);
 
   int list_keys_init(const string& section, void **phandle);
   int list_keys_init(const string& section, const string& marker, void **phandle);
@@ -206,6 +225,7 @@ public:
   int put() override;
 
   virtual int put_checked(RGWMetadataObject *_old_obj);
+  virtual void encode_obj(bufferlist *bl) {}
 };
 
 
index baa928b2b879352c35f33323199fcb3d0bec10e6..8a951d75ed71efd7d4a32055f35c19a35945fc5b 100644 (file)
@@ -78,10 +78,6 @@ class RGWOTPMetadataHandler : public RGWMetadataHandler {
     return 0;
   }
 
-  RGWSI_MetaBackend::Type required_be_type() override {
-    return RGWSI_MetaBackend::Type::MDBE_OTP;
-  }
-
   RGWMetadataObject *get_meta_obj(JSONObj *jo, const obj_version& objv, const ceph::real_time& mtime) override {
     otp_devices_list_t devices;
     try {
index 63663713f2496b7f6b4a1719be0ddeed8ddd8439..bb25c32f1108afa8a24b41d064e45544c8110daf 100644 (file)
@@ -7775,7 +7775,7 @@ int RGWRados::get_bucket_instance_info(RGWSysObjectCtx& obj_ctx, const rgw_bucke
     .set_mtime(pmtime)
     .set_attrs(pattrs)
     .set_pinfo(&info)
-    .set_optional_yield(y)
+    .set_yield(y)
     .exec();
 
   if (r < 0) {
@@ -7831,7 +7831,7 @@ int RGWRados::get_bucket_info(RGWSysObjectCtx& obj_ctx,
     .set_mtime(pmtime)
     .set_attrs(pattrs)
     .set_pinfo(&info)
-    .set_optional_yield(y)
+    .set_yield(y)
     .exec();
   if (r < 0) {
     return r;
index 4c85830910bd45eadd071b001afb6865001ac800..05e0e53d0acf7684720b0ea0ec8f2a372c1438ca 100644 (file)
@@ -37,8 +37,10 @@ int RGWRole::store_info(bool exclusive)
 
   bufferlist bl;
   encode(*this, bl);
-  return rgw_put_system_obj(store, store->svc.zone->get_zone_params().roles_pool, oid,
-                bl, exclusive, NULL, real_time(), NULL);
+
+  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
+  return rgw_put_system_obj(obj_ctx, store->svc.zone->get_zone_params().roles_pool, oid,
+                            bl, exclusive, NULL, real_time(), NULL);
 }
 
 int RGWRole::store_name(bool exclusive)
@@ -51,7 +53,9 @@ int RGWRole::store_name(bool exclusive)
   bufferlist bl;
   using ceph::encode;
   encode(nameToId, bl);
-  return rgw_put_system_obj(store, store->svc.zone->get_zone_params().roles_pool, oid,
+
+  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
+  return rgw_put_system_obj(obj_ctx, store->svc.zone->get_zone_params().roles_pool, oid,
               bl, exclusive, NULL, real_time(), NULL);
 }
 
@@ -60,7 +64,8 @@ int RGWRole::store_path(bool exclusive)
   string oid = tenant + get_path_oid_prefix() + path + get_info_oid_prefix() + id;
 
   bufferlist bl;
-  return rgw_put_system_obj(store, store->svc.zone->get_zone_params().roles_pool, oid,
+  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
+  return rgw_put_system_obj(obj_ctx, store->svc.zone->get_zone_params().roles_pool, oid,
               bl, exclusive, NULL, real_time(), NULL);
 }
 
index c0320b3af2dc139578bfb6f4a9b685abed45c416..c85eef7647a2e11ea5a5786172f408fd2531ba1e 100644 (file)
@@ -27,6 +27,7 @@
 #include "cls/lock/cls_lock_client.h"
 
 #include "services/svc_zone.h"
+#include "services/svc_mdlog.h"
 #include "services/svc_meta.h"
 
 #include <boost/asio/yield.hpp>
index ce1cc7f809af0b2d495d04359c23caeb901e6696..ba65666642db67a974c50e06367f6f1194a16573 100644 (file)
@@ -141,7 +141,7 @@ int rgw_user_get_all_buckets_stats(RGWRados *store, const rgw_user& user_id, map
  * Save the given user information to storage.
  * Returns: 0 on success, -ERR# on failure.
  */
-int rgw_store_user_info(RGWSI_User *user_svc,
+int rgw_store_user_info(RGWUserCtl& user_ctl,
                         RGWUserInfo& info,
                         RGWUserInfo *old_info,
                         RGWObjVersionTracker *objv_tracker,
@@ -149,80 +149,19 @@ int rgw_store_user_info(RGWSI_User *user_svc,
                         bool exclusive,
                         map<string, bufferlist> *pattrs)
 {
-  auto user = user_svc->user(info.user_id);
-
-  return user.set_op()
-    .set_exclusive(exclusive)
-    .set_mtime(mtime)
-    .set_attrs(pattrs)
-    .set_old_info(old_info)
-    .set_objv_tracker(objv_tracker)
-    .exec();
-}
-
-struct user_info_entry {
-  RGWUserInfo info;
-  RGWObjVersionTracker objv_tracker;
-  real_time mtime;
-};
-
-static RGWChainedCacheImpl<user_info_entry> uinfo_cache;
-
-int rgw_get_user_info_from_index(RGWRados * const store,
-                                 const string& key,
-                                 const rgw_pool& pool,
-                                 RGWUserInfo& info,
-                                 RGWObjVersionTracker * const objv_tracker,
-                                 real_time * const pmtime)
-{
-  if (auto e = uinfo_cache.find(key)) {
-    info = e->info;
-    if (objv_tracker)
-      *objv_tracker = e->objv_tracker;
-    if (pmtime)
-      *pmtime = e->mtime;
-    return 0;
-  }
-
-  user_info_entry e;
-  bufferlist bl;
-  RGWUID uid;
-  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
-
-  int ret = rgw_get_system_obj(obj_ctx, pool, key, bl, NULL, &e.mtime, null_yield);
-  if (ret < 0)
-    return ret;
-
-  rgw_cache_entry_info cache_info;
-
-  auto iter = bl.cbegin();
-  try {
-    decode(uid, iter);
-    int ret = rgw_get_user_info_by_uid(store, uid.user_id, e.info, &e.objv_tracker, NULL, &cache_info);
-    if (ret < 0) {
-      return ret;
-    }
-  } catch (buffer::error& err) {
-    ldout(store->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl;
-    return -EIO;
-  }
-
-  uinfo_cache.put(store->svc.cache, key, &e, { &cache_info });
-
-  info = e.info;
-  if (objv_tracker)
-    *objv_tracker = e.objv_tracker;
-  if (pmtime)
-    *pmtime = e.mtime;
-
-  return 0;
+  return user_ctl.store_info(info, RGWUserCtl::PutParams()
+                                   .set_old_info(&info)
+                                   .set_objv_tracker(objv_tracker)
+                                   .set_mtime(mtime)
+                                   .set_exclusive(exclusive)
+                                   .set_attrs(pattrs));
 }
 
 /**
  * Given a uid, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-int rgw_get_user_info_by_uid(RGWRados *store,
+int rgw_get_user_info_by_uid(RGWUserCtl& user_ctl,
                              const rgw_user& uid,
                              RGWUserInfo& info,
                              RGWObjVersionTracker * const objv_tracker,
@@ -230,105 +169,70 @@ int rgw_get_user_info_by_uid(RGWRados *store,
                              rgw_cache_entry_info * const cache_info,
                              map<string, bufferlist> * const pattrs)
 {
-#warning FIXME
+  return user_ctl.get_info_by_uid(uid, RGWUserCtl::GetParams()
+                                       .set_info(&info)
+                                       .set_objv_tracker(objv_tracker)
+                                       .set_mtime(pmtime)
+                                       .set_cache_info(cache_info)
+                                       .set_attrs(pattrs));
 }
 
 /**
  * Given an email, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-int rgw_get_user_info_by_email(RGWRados *store, string& email, RGWUserInfo& info,
+int rgw_get_user_info_by_email(RGWUserCtl& user_ctl, string& email, RGWUserInfo& info,
                                RGWObjVersionTracker *objv_tracker, real_time *pmtime)
 {
-  return rgw_get_user_info_from_index(store, email, store->svc.zone->get_zone_params().user_email_pool, info, objv_tracker, pmtime);
+  return user_ctl.get_info_by_email(email, RGWUserCtl::GetParams()
+                                           .set_info(&info)
+                                           .set_objv_tracker(objv_tracker)
+                                           .set_mtime(pmtime));
 }
 
 /**
  * Given an swift username, finds the user_info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-extern int rgw_get_user_info_by_swift(RGWRados * const store,
+extern int rgw_get_user_info_by_swift(RGWUserCtl& user_ctl,
                                       const string& swift_name,
                                       RGWUserInfo& info,        /* out */
                                       RGWObjVersionTracker * const objv_tracker,
                                       real_time * const pmtime)
 {
-  return rgw_get_user_info_from_index(store, swift_name,
-                                      store->svc.zone->get_zone_params().user_swift_pool,
-                                      info, objv_tracker, pmtime);
+  return user_ctl.get_info_by_swift(swift_name, RGWUserCtl::GetParams()
+                                                .set_info(&info)
+                                                .set_objv_tracker(objv_tracker)
+                                                .set_mtime(pmtime));
 }
 
 /**
  * Given an access key, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-extern int rgw_get_user_info_by_access_key(RGWRados* store,
+extern int rgw_get_user_info_by_access_key(RGWUserCtl& user_ctl,
                                            const std::string& access_key,
                                            RGWUserInfo& info,
                                            RGWObjVersionTracker* objv_tracker,
                                            real_time *pmtime)
 {
-  return rgw_get_user_info_from_index(store, access_key,
-                                      store->svc.zone->get_zone_params().user_keys_pool,
-                                      info, objv_tracker, pmtime);
+  return user_ctl.get_info_by_access_key(access_key, RGWUserCtl::GetParams()
+                                                     .set_info(&info)
+                                                     .set_objv_tracker(objv_tracker)
+                                                     .set_mtime(pmtime));
 }
 
-int rgw_get_user_attrs_by_uid(RGWRados *store,
+int rgw_get_user_attrs_by_uid(RGWUserCtl& user_ctl,
                               const rgw_user& user_id,
                               map<string, bufferlist>& attrs,
                               RGWObjVersionTracker *objv_tracker)
 {
-  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
-  rgw_raw_obj obj(store->svc.zone->get_zone_params().user_uid_pool, user_id.to_str());
-  auto src = obj_ctx.get_obj(obj);
-
-  return src.rop()
-            .set_attrs(&attrs)
-            .set_objv_tracker(objv_tracker)
-            .stat(null_yield);
-}
-
-int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key)
-{
-  rgw_raw_obj obj(store->svc.zone->get_zone_params().user_keys_pool, access_key.id);
-  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
-  auto sysobj = obj_ctx.get_obj(obj);
-  return sysobj.wop().remove(null_yield);
-}
-
-int rgw_remove_uid_index(RGWRados *store, rgw_user& uid)
-{
-  RGWObjVersionTracker objv_tracker;
-  RGWUserInfo info;
-  int ret = rgw_get_user_info_by_uid(store, uid, info, &objv_tracker, NULL);
-  if (ret < 0)
-    return ret;
-
-  string oid = uid.to_str();
-  ret = store->svc.meta->get_mgr()->remove_entry(user_meta_handler, oid, &objv_tracker);
-  if (ret < 0)
-    return ret;
-
-  return 0;
-}
-
-int rgw_remove_email_index(RGWRados *store, string& email)
-{
-  if (email.empty()) {
-    return 0;
-  }
-  rgw_raw_obj obj(store->svc.zone->get_zone_params().user_email_pool, email);
-  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
-  auto sysobj = obj_ctx.get_obj(obj);
-  return sysobj.wop().remove(null_yield);
-}
+  RGWUserInfo user_info;
 
-int rgw_remove_swift_name_index(RGWRados *store, string& swift_name)
-{
-  rgw_raw_obj obj(store->svc.zone->get_zone_params().user_swift_pool, swift_name);
-  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
-  auto sysobj = obj_ctx.get_obj(obj);
-  return sysobj.wop().remove(null_yield);
+  return user_ctl.get_info_by_uid(user_id, RGWUserCtl::GetParams()
+                                           .set_info(&user_info)
+                                           .set_objv_tracker(objv_tracker)
+                                           .set_attrs(&attrs));
 }
 
 /**
@@ -337,63 +241,10 @@ int rgw_remove_swift_name_index(RGWRados *store, string& swift_name)
  * from the user and user email pools. This leaves the pools
  * themselves alone, as well as any ACLs embedded in object xattrs.
  */
-int rgw_delete_user(RGWRados *store, RGWUserInfo& info, RGWObjVersionTracker& objv_tracker) {
-  int ret;
-
-  map<string, RGWAccessKey>::iterator kiter = info.access_keys.begin();
-  for (; kiter != info.access_keys.end(); ++kiter) {
-    ldout(store->ctx(), 10) << "removing key index: " << kiter->first << dendl;
-    ret = rgw_remove_key_index(store, kiter->second);
-    if (ret < 0 && ret != -ENOENT) {
-      ldout(store->ctx(), 0) << "ERROR: could not remove " << kiter->first << " (access key object), should be fixed (err=" << ret << ")" << dendl;
-      return ret;
-    }
-  }
-
-  map<string, RGWAccessKey>::iterator siter = info.swift_keys.begin();
-  for (; siter != info.swift_keys.end(); ++siter) {
-    RGWAccessKey& k = siter->second;
-    ldout(store->ctx(), 10) << "removing swift subuser index: " << k.id << dendl;
-    /* check if swift mapping exists */
-    ret = rgw_remove_swift_name_index(store, k.id);
-    if (ret < 0 && ret != -ENOENT) {
-      ldout(store->ctx(), 0) << "ERROR: could not remove " << k.id << " (swift name object), should be fixed (err=" << ret << ")" << dendl;
-      return ret;
-    }
-  }
-
-  ldout(store->ctx(), 10) << "removing email index: " << info.user_email << dendl;
-  ret = rgw_remove_email_index(store, info.user_email);
-  if (ret < 0 && ret != -ENOENT) {
-    ldout(store->ctx(), 0) << "ERROR: could not remove email index object for "
-        << info.user_email << ", should be fixed (err=" << ret << ")" << dendl;
-    return ret;
-  }
-
-  string buckets_obj_id;
-  rgw_get_buckets_obj(info.user_id, buckets_obj_id);
-  rgw_raw_obj uid_bucks(store->svc.zone->get_zone_params().user_uid_pool, buckets_obj_id);
-  ldout(store->ctx(), 10) << "removing user buckets index" << dendl;
-  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
-  auto sysobj = obj_ctx.get_obj(uid_bucks);
-  ret = sysobj.wop().remove(null_yield);
-  if (ret < 0 && ret != -ENOENT) {
-    ldout(store->ctx(), 0) << "ERROR: could not remove " << info.user_id << ":" << uid_bucks << ", should be fixed (err=" << ret << ")" << dendl;
-    return ret;
-  }
-
-  string key;
-  info.user_id.to_str(key);
-  
-  rgw_raw_obj uid_obj(store->svc.zone->get_zone_params().user_uid_pool, key);
-  ldout(store->ctx(), 10) << "removing user index: " << info.user_id << dendl;
-  ret = store->get_mgr()->remove_entry(user_meta_handler, key, &objv_tracker);
-  if (ret < 0 && ret != -ENOENT && ret  != -ECANCELED) {
-    ldout(store->ctx(), 0) << "ERROR: could not remove " << info.user_id << ":" << uid_obj << ", should be fixed (err=" << ret << ")" << dendl;
-    return ret;
-  }
-
-  return 0;
+int rgw_delete_user(RGWUserCtl& user_ctl, RGWUserInfo& info, RGWObjVersionTracker& objv_tracker) {
+  return user_ctl.remove_info(info, RGWUserCtl::RemoveParams()
+                                    .set_objv_tracker(&objv_tracker)
+                                    .set_yield(null_yield));
 }
 
 static bool char_is_unreserved_url(char c)
@@ -499,50 +350,6 @@ static void set_err_msg(std::string *sink, std::string msg)
     *sink = msg;
 }
 
-static bool remove_old_indexes(RGWRados *store,
-         RGWUserInfo& old_info, RGWUserInfo& new_info, std::string *err_msg)
-{
-  int ret;
-  bool success = true;
-
-  if (!old_info.user_id.empty() &&
-      old_info.user_id.compare(new_info.user_id) != 0) {
-    if (old_info.user_id.tenant != new_info.user_id.tenant) {
-      ldout(store->ctx(), 0) << "ERROR: tenant mismatch: " << old_info.user_id.tenant << " != " << new_info.user_id.tenant << dendl;
-      return false;
-    }
-    ret = rgw_remove_uid_index(store, old_info.user_id);
-    if (ret < 0 && ret != -ENOENT) {
-      set_err_msg(err_msg, "ERROR: could not remove index for uid " + old_info.user_id.to_str());
-      success = false;
-    }
-  }
-
-  if (!old_info.user_email.empty() &&
-      old_info.user_email.compare(new_info.user_email) != 0) {
-    ret = rgw_remove_email_index(store, old_info.user_email);
-  if (ret < 0 && ret != -ENOENT) {
-      set_err_msg(err_msg, "ERROR: could not remove index for email " + old_info.user_email);
-      success = false;
-    }
-  }
-
-  map<string, RGWAccessKey>::iterator old_iter;
-  for (old_iter = old_info.swift_keys.begin(); old_iter != old_info.swift_keys.end(); ++old_iter) {
-    RGWAccessKey& swift_key = old_iter->second;
-    map<string, RGWAccessKey>::iterator new_iter = new_info.swift_keys.find(swift_key.id);
-    if (new_iter == new_info.swift_keys.end()) {
-      ret = rgw_remove_swift_name_index(store, swift_key.id);
-      if (ret < 0 && ret != -ENOENT) {
-        set_err_msg(err_msg, "ERROR: could not remove index for swift_name " + swift_key.id);
-        success = false;
-      }
-    }
-  }
-
-  return success;
-}
-
 /*
  * Dump either the full user info or a subset to a formatter.
  *
@@ -1755,24 +1562,12 @@ int RGWUser::update(RGWUserAdminOpState& op_state, std::string *err_msg)
     return -EINVAL;
   }
 
-  if (is_populated()) {
-    ret = rgw_store_user_info(store, user_info, &old_info, &op_state.objv, real_time(), false);
-    if (ret < 0) {
-      set_err_msg(err_msg, "unable to store user info");
-      return ret;
-    }
+  RGWUserInfo *pold_info = (is_populated() ? &old_info : nullptr);
 
-    ret = remove_old_indexes(store, old_info, user_info, &subprocess_msg);
-    if (ret < 0) {
-      set_err_msg(err_msg, "unable to remove old user info, " + subprocess_msg);
-      return ret;
-    }
-  } else {
-    ret = rgw_store_user_info(store, user_info, NULL, &op_state.objv, real_time(), false);
-    if (ret < 0) {
-      set_err_msg(err_msg, "unable to store user info");
-      return ret;
-    }
+  ret = rgw_store_user_info(store, user_info, pold_info, &op_state.objv, real_time(), false);
+  if (ret < 0) {
+    set_err_msg(err_msg, "unable to store user info");
+    return ret;
   }
 
   old_info = user_info;
@@ -2268,7 +2063,7 @@ int RGWUser::list(RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher)
   do {
     std::list<std::string> keys;
     left = op_state.max_entries - count;
-    ret = meta_mgr->get_->list_keys_next(handle, left, keys, &truncated);
+    ret = meta_mgr->list_keys_next(handle, left, keys, &truncated);
     if (ret < 0 && ret != -ENOENT) {
       return ret;
     } if (ret != -ENOENT) {
@@ -2648,70 +2443,25 @@ int RGWUserAdminOp_Caps::remove(RGWRados *store, RGWUserAdminOpState& op_state,
 }
 
 class RGWUserMetadataHandler : public RGWMetadataHandler {
-  int read_user_info_entry(RGWSI_MetaBackend::Context *ctx,
-                           string& entry,
-                           RGWUserInfo& info,
-                           RGWObjVersionTracker * const objv_tracker,
-                           real_time * const pmtime,
-                           rgw_cache_entry_info * const cache_info,
-                           map<string, bufferlist> * const pattrs) {
-    bufferlist bl;
-    RGWUID user_id;
-
-    RGWSI_MBSObj_GetParams params = {
-      pmtime,
-      std::nullopt, /* _bl */
-      &bl,
-      pattrs,
-      nullptr, /* cache_info */
-      null_yield,
-    };
-    int ret = meta_be->get_entry(ctx, params, objv_tracker);
-    if (ret < 0) {
-      return ret;
-    }
-
-    auto iter = bl.cbegin();
-    try {
-      decode(user_id, iter);
-      if (user_id.user_id.to_str().compare(entry) != 0) {
-        lderr(meta_be->ctx())  << "ERROR: rgw_get_user_info_by_uid(): user id mismatch: " << user_id.user_id.to_str() << " != " << entry << dendl;
-        return -EIO;
-      }
-      if (!iter.end()) {
-        decode(info, iter);
-      }
-    } catch (buffer::error& err) {
-      ldout(meta_be->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl;
-      return -EIO;
-    }
-
-    return 0;
-  }
+public:
+  struct Svc {
+    RGWSI_User *user{nullptr};
+  } svc;
 
-  int store_user_info_entry(RGWSI_MetaBackend::Context *ctx,
-                            string& entry,
-                            RGWUserInfo& info,
-                            RGWUserInfo *old_info,
-                            RGWObjVersionTracker *objv_tracker,
-                            real_time& mtime,
-                            bool exclusive,
-                            map<string, bufferlist> *pattrs) {
-    return do_store_user_info(this, ctx, info, old_info,
-                              objv_tracker,
-                              mtime, exclusive, pattrs);
+  RGWUserMetadataHandler(RGWSI_User *user_svc) {
+    svc.user = user_svc;
   }
 
-public:
   string get_type() override { return "user"; }
 
-  int do_get(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject **obj) override {
+  int do_get(RGWSI_MetaBackend::Context *ctx, string& entry, RGWMetadataObject **obj, optional_yield y) override {
     RGWUserCompleteInfo uci;
     RGWObjVersionTracker objv_tracker;
     real_time mtime;
 
-    int ret = read_user_info_entry(ctx, entry, uci.info, &objv_tracker,
-                                   &mtime, nullptr, &uci.attrs);
+    int ret = svc.user->read_user_info(ctx, &uci.info, &objv_tracker,
+                                       &mtime, nullptr, &uci.attrs,
+                                       y);
     if (ret < 0) {
       return ret;
     }
@@ -2725,6 +2475,7 @@ public:
   int do_put(RGWSI_MetaBackend::Context *ctx, string& entry,
              RGWMetadataObject *obj,
              RGWObjVersionTracker& objv_tracker,
+             optional_yield y,
              RGWMDLogSyncType type) override;
 
   struct list_keys_info {
@@ -2732,21 +2483,22 @@ public:
     RGWListRawObjsCtx ctx;
   };
 
-  int do_remove(RGWSI_MetaBackend::Context *ctx, string& entry, RGWObjVersionTracker& objv_tracker) {
+  int do_remove(RGWSI_MetaBackend::Context *ctx, string& entry, RGWObjVersionTracker& objv_tracker,
+                optional_yield y) {
     RGWUserInfo info;
 
-    rgw_user uid(entry);
-
-    int ret = read_user_info_entry(ctx, entry, uci.info, nullptr,
-                                   nullptr, nullptr, nullptr);
+    int ret = svc.user->read_user_info(ctx, &info, nullptr,
+                                       nullptr, nullptr, nullptr,
+                                       y);
     if (ret < 0) {
       return ret;
     }
 
-    return rgw_delete_user(store, info, objv_tracker);
+    return svc.user->remove_user_info(ctx, info, &objv_tracker,
+                                      y);
   }
 
-  int list_keys_init(RGWRados *store, const string& marker, void **phandle) override
+  int list_keys_init(const string& marker, void **phandle) override
   {
     auto info = std::make_unique<list_keys_info>();
 
@@ -2811,41 +2563,47 @@ public:
 class RGWMetadataHandlerPut_User : public RGWMetadataHandlerPut_SObj
 {
   RGWUserMetadataHandler *handler;
-  RGWUserEntryMetadataObject *obj;
+  RGWUserMetadataObject *uobj;
 public:
   RGWMetadataHandlerPut_User(RGWUserMetadataHandler *_handler,
-                                       RGWSI_MetaBackend::Context *ctx, string& entry,
-                                       RGWMetadataObject *_obj, RGWObjVersionTracker& objv_tracker,
-                                       RGWMDLogSyncType type) : RGWMetadataHandlerPut_SObj(ctx, entry, obj, objv_tracker, type),
+                             RGWSI_MetaBackend::Context *ctx, string& entry,
+                             RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
+                             optional_yield y,
+                             RGWMDLogSyncType type) : RGWMetadataHandlerPut_SObj(handler, ctx, entry, obj, objv_tracker, y, type),
                                                                 handler(_handler) {
-    obj = static_cast<RGWUserMetadataObject *>(_obj);
+    uobj = static_cast<RGWUserMetadataObject *>(obj);
   }
 
   int put_checked(RGWMetadataObject *_old_obj) override;
 };
 
-int RGWUserMetaHandler::do_put(RGWSI_MetaBackend::Context *ctx, string& entry,
-                               RGWMetadataObject *obj,
-                               RGWObjVersionTracker& objv_tracker,
-                               RGWMDLogSyncType type)
+int RGWUserMetadataHandler::do_put(RGWSI_MetaBackend::Context *ctx, string& entry,
+                                   RGWMetadataObject *obj,
+                                   RGWObjVersionTracker& objv_tracker,
+                                   optional_yield y,
+                                   RGWMDLogSyncType type)
 {
-  RGWMetadataHandlerPut_User op(this, ctx, entry, obj, objv_tracker, type);
-  return do_put_operation(&op);
+  RGWMetadataHandlerPut_User op(this, ctx, entry, obj, objv_tracker, y, type);
+  return do_put_operate(&op);
 }
 
 int RGWMetadataHandlerPut_User::put_checked(RGWMetadataObject *_old_obj)
 {
   RGWUserMetadataObject *old_obj = static_cast<RGWUserMetadataObject *>(_old_obj);
-  RGWUserCompleteInfo& uci = obj->get_uci();
+  RGWUserCompleteInfo& uci = uobj->get_uci();
 
-  map<string, bufferlist> *pattrs = nullptr;
+  map<string, bufferlist> *pattrs{nullptr};
   if (uci.has_attrs) {
     pattrs = &uci.attrs;
   }
 
-  RGWUserInfo *pold_info = (old_obj ? &old_obj->info : nullptr);
+  RGWUserInfo *pold_info = (old_obj ? &old_obj->get_uci().info : nullptr);
 
-  ret = store_user_info_entry(ctx, entry, uci.info, &old_info, &objv_tracker, mtime, false, pattrs);
+  auto mtime = obj->get_mtime();
+
+  int ret = handler->svc.user->store_user_info(ctx, uci.info, pold_info,
+                                               &objv_tracker, mtime,
+                                               false, pattrs, y);
   if (ret < 0) {
     return ret;
   }
@@ -2853,11 +2611,86 @@ int RGWMetadataHandlerPut_User::put_checked(RGWMetadataObject *_old_obj)
   return STATUS_APPLIED;
 }
 
-RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc() {
-  return new RGWUserMetadataHandler;
+
+int RGWUserCtl::get_info_by_uid(const rgw_user& uid, GetParams& params)
+
+{
+  string key = RGWSI_User::get_meta_key(uid);
+
+  return umhandler->call_with_ctx(key, [&](RGWSI_MetaBackend::Context *ctx) {
+    return svc.user->read_user_info(ctx,
+                                    params.info,
+                                    params.objv_tracker,
+                                    params.mtime,
+                                    params.cache_info,
+                                    params.attrs,
+                                    params.y);
+  });
+}
+
+int RGWUserCtl::get_info_by_email(const string& email, GetParams& params)
+
+{
+  return umhandler->call_with_ctx([&](RGWSI_MetaBackend::Context *ctx) {
+    return svc.user->get_user_info_by_email(ctx, email,
+                                            params.info,
+                                            params.objv_tracker,
+                                            params.mtime,
+                                            params.y);
+  });
+}
+
+int RGWUserCtl::get_info_by_swift(const string& swift_name, GetParams& params)
+{
+  return umhandler->call_with_ctx([&](RGWSI_MetaBackend::Context *ctx) {
+    return svc.user->get_user_info_by_swift(ctx, swift_name,
+                                            params.info,
+                                            params.objv_tracker,
+                                            params.mtime,
+                                            params.y);
+  });
 }
 
-void rgw_user_init(RGWRados *store)
+int RGWUserCtl::get_info_by_access_key(const string& access_key, GetParams& params)
 {
-  uinfo_cache.init(store->svc.cache);
+  return umhandler->call_with_ctx([&](RGWSI_MetaBackend::Context *ctx) {
+    return svc.user->get_user_info_by_swift(ctx, access_key,
+                                            params.info,
+                                            params.objv_tracker,
+                                            params.mtime,
+                                            params.y);
+  });
+}
+
+int RGWUserCtl::store_info(const RGWUserInfo& info, PutParams& params)
+
+{
+  string key = RGWSI_User::get_meta_key(info.user_id);
+
+  return umhandler->call_with_ctx(key, [&](RGWSI_MetaBackend::Context *ctx) {
+    return svc.user->store_user_info(ctx, info,
+                                     params.old_info,
+                                     params.objv_tracker,
+                                     params.mtime,
+                                     params.exclusive,
+                                     params.attrs,
+                                     params.y);
+  });
 }
+
+int RGWUserCtl::remove_info(const RGWUserInfo& info, RemoveParams& params)
+
+{
+  string key = RGWSI_User::get_meta_key(info.user_id);
+
+  return umhandler->call_with_ctx(key, [&](RGWSI_MetaBackend::Context *ctx) {
+    return svc.user->remove_user_info(ctx, info,
+                                      params.objv_tracker,
+                                      params.y);
+  });
+}
+
+RGWMetadataHandler *RGWUserMetaHandlerAllocator::alloc(RGWSI_User *user_svc) {
+  return new RGWUserMetadataHandler(user_svc);
+}
+
index c92a9c018ca25cc48fc55697013255f86ee0b6ee..16889fbdfbb3d099ec9762ca8c0929f979dd238b 100644 (file)
@@ -27,6 +27,7 @@
 #define XMLNS_AWS_S3 "http://s3.amazonaws.com/doc/2006-03-01/"
 
 class RGWRados;
+class RGWUserCtl;
 
 /**
  * A string wrapper that includes encode/decode functions
@@ -62,36 +63,38 @@ extern void rgw_get_anon_user(RGWUserInfo& info);
  * Save the given user information to storage.
  * Returns: 0 on success, -ERR# on failure.
  */
-extern int rgw_store_user_info(RGWRados *store,
+extern int rgw_store_user_info(RGWUserCtl& user_ctl,
                                RGWUserInfo& info,
                                RGWUserInfo *old_info,
                                RGWObjVersionTracker *objv_tracker,
                                real_time mtime,
                                bool exclusive,
-                               map<string, bufferlist> *pattrs = NULL);
+                               map<string, bufferlist> *pattrs = nullptr);
 
 /**
  * Given an user_id, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-extern int rgw_get_user_info_by_uid(RGWRados *store,
+extern int rgw_get_user_info_by_uid(RGWUserCtl& user_ctl,
                                     const rgw_user& user_id,
                                     RGWUserInfo& info,
-                                    RGWObjVersionTracker *objv_tracker = NULL,
-                                    real_time *pmtime                     = NULL,
-                                    rgw_cache_entry_info *cache_info   = NULL,
-                                    map<string, bufferlist> *pattrs    = NULL);
+                                    RGWObjVersionTracker *objv_tracker = nullptr,
+                                    real_time *pmtime                  = nullptr,
+                                    rgw_cache_entry_info *cache_info   = nullptr,
+                                    map<string, bufferlist> *pattrs    = nullptr);
 /**
  * Given an email, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-extern int rgw_get_user_info_by_email(RGWRados *store, string& email, RGWUserInfo& info,
-                                      RGWObjVersionTracker *objv_tracker = NULL, real_time *pmtime = NULL);
+extern int rgw_get_user_info_by_email(RGWUserCtl& user_ctl,
+                                      string& email, RGWUserInfo& info,
+                                      RGWObjVersionTracker *objv_tracker = NULL,
+                                      real_time *pmtime = nullptr);
 /**
  * Given an swift username, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-extern int rgw_get_user_info_by_swift(RGWRados *store,
+extern int rgw_get_user_info_by_swift(RGWUserCtl& user_ctl,
                                       const string& swift_name,
                                       RGWUserInfo& info,        /* out */
                                       RGWObjVersionTracker *objv_tracker = nullptr,
@@ -100,7 +103,7 @@ extern int rgw_get_user_info_by_swift(RGWRados *store,
  * Given an access key, finds the user info associated with it.
  * returns: 0 on success, -ERR# on failure (including nonexistence)
  */
-extern int rgw_get_user_info_by_access_key(RGWRados* store,
+extern int rgw_get_user_info_by_access_key(RGWUserCtl& user_ctl,
                                            const std::string& access_key,
                                            RGWUserInfo& info,
                                            RGWObjVersionTracker* objv_tracker = nullptr,
@@ -110,22 +113,14 @@ extern int rgw_get_user_info_by_access_key(RGWRados* store,
  * and put it into @attrs.
  * Returns: 0 on success, -ERR# on failure.
  */
-extern int rgw_get_user_attrs_by_uid(RGWRados *store,
+extern int rgw_get_user_attrs_by_uid(RGWUserCtl& user_ctl,
                                      const rgw_user& user_id,
                                      map<string, bufferlist>& attrs,
-                                     RGWObjVersionTracker *objv_tracker = NULL);
+                                     RGWObjVersionTracker *objv_tracker = nullptr);
 /**
  * Given an RGWUserInfo, deletes the user and its bucket ACLs.
  */
-extern int rgw_delete_user(RGWRados *store, RGWUserInfo& user, RGWObjVersionTracker& objv_tracker);
-
-/*
- * remove the different indexes
- */
-extern int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key);
-extern int rgw_remove_uid_index(RGWRados *store, rgw_user& uid);
-extern int rgw_remove_email_index(RGWRados *store, string& email);
-extern int rgw_remove_swift_name_index(RGWRados *store, string& swift_name);
+extern int rgw_delete_user(RGWUserCtl& user_ctl, RGWUserInfo& user, RGWObjVersionTracker& objv_tracker);
 
 extern void rgw_perm_to_str(uint32_t mask, char *buf, int len);
 extern uint32_t rgw_str_to_perm(const char *str);
@@ -788,6 +783,7 @@ struct RGWUserCompleteInfo {
 class RGWUserMetadataObject : public RGWMetadataObject {
   RGWUserCompleteInfo uci;
 public:
+  RGWUserMetadataObject() {}
   RGWUserMetadataObject(const RGWUserCompleteInfo& _uci, obj_version& v, real_time m)
       : uci(_uci) {
     objv = v;
@@ -803,12 +799,130 @@ public:
   }
 };
 
-class RGWUserMetaHandlerAllocator {
+class RGWUserMetadataHandler;
+
+class RGWUserCtl
+{
+  struct Svc {
+    RGWSI_Zone *zone{nullptr};
+    RGWSI_User *user{nullptr};
+  } svc;
+
+  RGWUserMetadataHandler *umhandler;
+  
 public:
-  static RGWMetadataHandler *alloc();
+  RGWUserCtl(RGWSI_Zone *zone_svc,
+             RGWSI_User *user_svc,
+             RGWUserMetadataHandler *_umhandler) : umhandler(_umhandler) {
+    svc.zone = zone_svc;
+    svc.user = user_svc;
+  }
+
+  struct GetParams {
+    RGWUserInfo *info{nullptr};
+    RGWObjVersionTracker *objv_tracker{nullptr};
+    ceph::real_time *mtime{nullptr};
+    rgw_cache_entry_info *cache_info{nullptr};
+    map<string, bufferlist> *attrs{nullptr};
+    optional_yield y{null_yield};
+
+    GetParams& set_info(RGWUserInfo *_info) {
+      info = _info;
+      return *this;
+    }
+
+    GetParams& set_objv_tracker(RGWObjVersionTracker *_objv_tracker) {
+      objv_tracker = _objv_tracker;
+      return *this;
+    }
+
+    GetParams& set_mtime(ceph::real_time *_mtime) {
+      mtime = _mtime;
+      return *this;
+    }
+
+    GetParams& set_cache_info(rgw_cache_entry_info *_cache_info) {
+      cache_info = _cache_info;
+      return *this;
+    }
+
+    GetParams& set_attrs(map<string, bufferlist> *_attrs) {
+      attrs = _attrs;
+      return *this;
+    }
+
+    RemoveParams& set_yield(optional_yield _y) {
+      y = _y;
+      return *this;
+    }
+  };
+
+  struct PutParams {
+    RGWUserInfo *old_info{nullptr};
+    RGWObjVersionTracker *objv_tracker{nullptr};
+    ceph::real_time mtime;
+    bool exclusive{false};
+    map<string, bufferlist> *attrs;
+    optional_yield y{null_yield};
+
+    PutParams& set_old_info(RGWUserInfo *_info) {
+      old_info = _info;
+      return *this;
+    }
+
+    PutParams& set_objv_tracker(RGWObjVersionTracker *_objv_tracker) {
+      objv_tracker = _objv_tracker;
+      return *this;
+    }
+
+    PutParams& set_mtime(const ceph::real_time& _mtime) {
+      mtime = _mtime;
+      return *this;
+    }
+
+    PutParams& set_exclusive(bool _exclusive) {
+      exclusive = _exclusive;
+      return *this;
+    }
+
+    PutParams& set_attrs(map<string, bufferlist> *_attrs) {
+      attrs = _attrs;
+      return *this;
+    }
+
+    RemoveParams& set_yield(optional_yield _y) {
+      y = _y;
+      return *this;
+    }
+  };
+
+  struct RemoveParams {
+    RGWObjVersionTracker *objv_tracker{nullptr};
+    optional_yield y{null_yield};
+
+    RemoveParams& set_objv_tracker(RGWObjVersionTracker *_objv_tracker) {
+      objv_tracker = _objv_tracker;
+      return *this;
+    }
+    RemoveParams& set_yield(optional_yield _y) {
+      y = _y;
+      return *this;
+    }
+  };
+
+  int get_info_by_uid(const rgw_user& uid, GetParams& params);
+  int get_info_by_email(const string& email, GetParams& params);
+  int get_info_by_swift(const string& swift_name, GetParams& params);
+  int get_info_by_access_key(const string& access_key, GetParams& params);
+
+  int store_info(const RGWUserInfo& info, PutParams& params);
+  int remove_info(const RGWUserInfo& info, RemoveParams& params);
 };
 
-void rgw_user_init(RGWRados *store);
+class RGWUserMetaHandlerAllocator {
+public:
+  static RGWMetadataHandler *alloc(RGWSI_User *user_svc);
+};
 
 
 #endif
index d818ae3100cc03c35b81cc33e6a91f38226ad0c4..01e7f475df07da49077fd1270876d3a1c7136ed9 100644 (file)
@@ -170,7 +170,7 @@ public:
         return *this;
       }
 
-      GetOp& set_optional_yield(optional_yield& _y) {
+      GetOp& set_yield(optional_yield& _y) {
         y = _y;
         return *this;
       }
@@ -224,7 +224,6 @@ public:
   Instance instance(RGWSysObjectCtx& _ctx,
                     const rgw_bucket& _bucket);
 
-
   int store_bucket_entrypoint_info(const string& tenant, const string& bucket_name,
                                   RGWBucketEntryPoint& be, bool exclusive,
                                   RGWObjVersionTracker *objv_tracker, real_time mtime,
@@ -235,3 +234,4 @@ public:
   int remove_bucket_instance_info(const rgw_bucket& bucket,
                                  RGWObjVersionTracker *objv_tracker);
 };
+
index c624bffdceb1f018e11c142a877a6fdf12e756c2..19cadfde2cf7ea0ac3bbc75609a47d8c3b74ef78 100644 (file)
@@ -93,15 +93,23 @@ public:
     Module *module{nullptr};
     std::string section;
     std::string key;
+
+    virtual void set_key(const string& _key) {
+      key = _key;
+    }
   };
 
   struct PutParams {
-    virtual ~PutParams() = 0;
-
     ceph::real_time mtime;
+
+    PutParams() {}
+    PutParams(const ceph::real_time& _mtime) : mtime(_mtime) {}
+    virtual ~PutParams() = 0;
   };
 
   struct GetParams {
+    GetParams() {}
+    GetParams(ceph::real_time *_pmtime) : pmtime(_pmtime) {}
     virtual ~GetParams();
 
     ceph::real_time *pmtime{nullptr};
@@ -123,34 +131,40 @@ public:
 
   virtual Type get_type() = 0;
 
-  virtual void init_ctx(RGWSI_MetaBackend_Handle handle, const string& key, RGWMetadataObject *obj, Context *ctx) = 0;
+  virtual void init_ctx(RGWSI_MetaBackend_Handle handle, Context *ctx) = 0;
 
   virtual GetParams *alloc_default_get_params(ceph::real_time *pmtime) = 0;
 
   /* these should be implemented by backends */
   virtual int get_entry(RGWSI_MetaBackend::Context *ctx,
                         RGWSI_MetaBackend::GetParams& params,
-                        RGWObjVersionTracker *objv_tracker) = 0;
+                        RGWObjVersionTracker *objv_tracker,
+                        optional_yield y) = 0;
   virtual int put_entry(RGWSI_MetaBackend::Context *ctx,
                         RGWSI_MetaBackend::PutParams& params,
-                        RGWObjVersionTracker *objv_tracker) = 0;
+                        RGWObjVersionTracker *objv_tracker,
+                        optional_yield y) = 0;
   virtual int remove_entry(Context *ctx,
                            RGWSI_MetaBackend::RemoveParams& params,
-                           RGWObjVersionTracker *objv_tracker) = 0;
+                           RGWObjVersionTracker *objv_tracker,
+                           optional_yield y) = 0;
 
   /* these should be called by handlers */
   virtual int get(Context *ctx,
                   GetParams &params,
-                  RGWObjVersionTracker *objv_tracker);
+                  RGWObjVersionTracker *objv_tracker,
+                  optional_yield y);
 
   virtual int put(Context *ctx,
                   PutParams& params,
                   RGWObjVersionTracker *objv_tracker,
+                  optional_yield y,
                   RGWMDLogSyncType sync_mode);
 
   virtual int remove(Context *ctx,
                      RemoveParams& params,
                      RGWObjVersionTracker *objv_tracker,
+                     optional_yield y,
                      RGWMDLogSyncType sync_mode);
 };
 
index 5a1bb0ed137038cf7089031fb29d2be48d073f56..16f8ac78ebcc0f087b3699c964c836070e39aeb4 100644 (file)
@@ -28,7 +28,7 @@ int RGWSI_MetaBackend_SObj::init_handler(RGWMetadataHandler *handler, RGWSI_Meta
   return 0;
 }
 
-void RGWSI_MetaBackend_SObj::init_ctx(RGWSI_MetaBackend_Handle handle, const string& key, RGWMetadataObject *obj, RGWSI_MetaBackend::Context *_ctx)
+void RGWSI_MetaBackend_SObj::init_ctx(RGWSI_MetaBackend_Handle handle, RGWSI_MetaBackend::Context *_ctx)
 {
   RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
   rgwsi_meta_be_sobj_handler_info *h = static_cast<rgwsi_meta_be_sobj_handler_info *>(handle);
@@ -36,10 +36,24 @@ void RGWSI_MetaBackend_SObj::init_ctx(RGWSI_MetaBackend_Handle handle, const str
   ctx->handle = handle;
   ctx->module = h->module;
   ctx->section = h->section;
-  ctx->key = key;
-  ctx->obj = obj;
-  ctx->obj_ctx.emplace(sysobj_svc->init_obj_ctx());
-  static_cast<RGWSI_MBSObj_Handler_Module *>(ctx->module)->get_pool_and_oid(key, ctx->pool, ctx->oid);
+  ctx->_obj_ctx.emplace(sysobj_svc->init_obj_ctx());
+  ctx->obj_ctx = &(*ctx->_obj_ctx);
+}
+
+void RGWSI_MetaBackend_SObj::Context_SObj::set_key(const string& _key)
+{
+  RGWSI_MetaBackend::Context::set_key(_key);
+  static_cast<RGWSI_MBSObj_Handler_Module *>(module)->get_pool_and_oid(key, pool, oid);
+}
+
+RGWSI_MetaBackend_SObj::Context_SObj *RGWSI_MetaBackend_SObj::Context_SObj::clone(const string& key)
+{
+  if (!_ctx2) {
+    _ctx2.reset(new RGWSI_MetaBackend_SObj::Context_SObj);
+  }
+  *_ctx2 = *this;
+  _ctx2->set_key(key);
+  return _ctx2.get();
 }
 
 RGWSI_MetaBackend::GetParams *RGWSI_MetaBackend_SObj::alloc_default_get_params(ceph::real_time *pmtime)
@@ -73,7 +87,7 @@ int RGWSI_MetaBackend_SObj::put_entry(RGWSI_MetaBackend::Context *_ctx,
   RGWSI_MBSObj_PutParams& params = static_cast<RGWSI_MBSObj_PutParams&>(_params);
 
   return rgw_put_system_obj(*ctx->obj_ctx, ctx->pool, ctx->oid, params.bl, params.exclusive,
-                            objv_tracker, params.mtime, params.pattrs);
+                            objv_tracker, params.mtime, params.y, params.pattrs);
 }
 
 int RGWSI_MetaBackend_SObj::remove_entry(RGWSI_MetaBackend::Context *_ctx,
@@ -87,6 +101,6 @@ int RGWSI_MetaBackend_SObj::remove_entry(RGWSI_MetaBackend::Context *_ctx,
   auto sysobj = ctx->obj_ctx->get_obj(k);
   return sysobj.wop()
                .set_objv_tracker(objv_tracker)
-               .remove(null_yield);
+               .remove(params.y);
 }
 
index 49c53c7a0dce287abffe13874d6d7809b5a4f55c..8b1cde67036473cd8b792ad0981575cc5751526a 100644 (file)
@@ -47,16 +47,45 @@ struct RGWSI_MBSObj_GetParams : public RGWSI_MetaBackend::GetParams {
   rgw_cache_entry_info *cache_info{nullptr};
   boost::optional<obj_version> refresh_version;
   optional_yield y{null_yield};
+
+  RGWSI_MBSObj_GetParams() {}
+  RGWSI_MBSObj_GetParams(bufferlist *_pbl,
+                         std::map<string, bufferlist> *_pattrs,
+                         ceph::real_time *_pmtime,
+                         optional_yield _y) : RGWSI_MetaBackend::GetParams(_pmtime),
+                                              pbl(_pbl),
+                                              pattrs(_pattrs),
+                                              y(_y) {}
 };
 
 struct RGWSI_MBSObj_PutParams : public RGWSI_MetaBackend::PutParams {
   bufferlist bl;
   map<string, bufferlist> *pattrs{nullptr};
   bool exclusive{false};
+  optional_yield y{null_yield};
+
+  RGWSI_MBSObj_PutParams() {}
+  RGWSI_MBSObj_PutParams(std::map<string, bufferlist> *_pattrs,
+                         const ceph::real_time& _mtime,
+                         optional_yield _y) : RGWSI_MetaBackend::PutParams(_mtime),
+                                              pattrs(_pattrs),
+                                              y(_y) {}
+  RGWSI_MBSObj_PutParams(bufferlist& _bl,
+                         std::map<string, bufferlist> *_pattrs,
+                         const ceph::real_time& _mtime,
+                         bool _exclusive,
+                         optional_yield _y) : RGWSI_MetaBackend::PutParams(_mtime),
+                                              bl(_bl),
+                                              pattrs(_pattrs),
+                                              exclusive(_exclusive),
+                                              y(_y) {}
 };
 
 struct RGWSI_MBSObj_RemoveParams : public RGWSI_MetaBackend::RemoveParams {
-  // nothing in here
+  optional_yield y{null_yield};
+
+  RGWSI_MBSObj_RemoveParams() {}
+  RGWSI_MBSObj_RemoveParams(optional_yield _y) : y(_y) {}
 };
 
 class RGWSI_MetaBackend_SObj : public RGWSI_MetaBackend
@@ -70,10 +99,25 @@ protected:
 
 public:
   struct Context_SObj : public RGWSI_MetaBackend::Context {
-    std::optional<RGWSysObjectCtx> obj_ctx;
-    RGWMetadataObject *obj;
+    std::optional<RGWSysObjectCtx> _obj_ctx;
+    RGWSysObjectCtx *obj_ctx{nullptr};
     rgw_pool pool;
     string oid;
+
+    std::unique_ptr<Context_SObj> _ctx2;
+
+    Context_SObj& operator=(const Context_SObj& rhs) {
+      _obj_ctx.reset();
+      obj_ctx = rhs.obj_ctx;
+      pool = rhs.pool;
+      oid = rhs.oid;
+      _ctx2.reset(); /* this isn't carried over */
+      return *this;
+    }
+
+    void set_key(const string& key) override;
+
+    Context_SObj *clone(const string& key);
   };
 
   RGWSI_MetaBackend_SObj(CephContext *cct);
@@ -89,7 +133,7 @@ public:
     sysobj_svc = _sysobj_svc;
   }
 
-  void init_ctx(RGWSI_MetaBackend_Handle handle, const string& key, RGWMetadataObject *obj, RGWSI_MetaBackend::Context *ctx) override;
+  void init_ctx(RGWSI_MetaBackend_Handle handle, RGWSI_MetaBackend::Context *ctx) override;
 
   RGWSI_MetaBackend::GetParams *alloc_default_get_params(ceph::real_time *pmtime) override;
 
index d7069f0a09b0d7d6d1f29de1105211745ab28f83..8d4b0e58b724ef16210c0d5e1cbbfe5a359a79cd 100644 (file)
@@ -19,11 +19,6 @@ RGWSI_User::RGWSI_User(CephContext *cct): RGWServiceInstance(cct) {
 RGWSI_User::~RGWSI_User() {
 }
 
-RGWSI_User::User RGWSI_User::user(RGWSysObjectCtx& _ctx,
-                                  const rgw_user& _user) {
-  return User(this, _ctx, _user);
-}
-
 void RGWSI_User::init(RGWSI_Zone *_zone_svc, RGWSI_SysObj *_sysobj_svc,
                         RGWSI_SysObj_Cache *_cache_svc, RGWSI_Meta *_meta_svc,
                         RGWSI_MetaBackend *_meta_be_svc,
@@ -44,7 +39,7 @@ int RGWSI_User::do_start()
   uinfo_cache->init(svc.cache);
 
   auto mm = svc.meta->get_mgr();
-  user_meta_handler = RGWUserMetaHandlerAllocator::alloc();
+  user_meta_handler = RGWUserMetaHandlerAllocator::alloc(this);
 
   int r = user_meta_handler->init(mm);
   if (r < 0) {
@@ -54,73 +49,21 @@ int RGWSI_User::do_start()
   return 0;
 }
 
-#warning clean me?
-#if 0
-int RGWSI_User::User::read_user_info(const rgw_user& user,
-                                     RGWUserInfo *info,
-                                     real_time *pmtime,
-                                     map<string, bufferlist> *pattrs,
-                                     boost::optional<obj_version> refresh_version)
-{
-#warning FIXME
-}
-
-int RGWSI_User::User::write_user_info(RGWUserInfo& info,
-                                      bool exclusive,
-                                      real_time mtime,
-                                      map<string, bufferlist> *pattrs)
-{
-#warning FIXME
-}
-#endif
-
-int RGWSI_User::User::GetOp::exec()
-{
-  int r = source.svc.user->read_user_info(source.user, &source.user_info,
-                                          pmtime, pattrs,
-                                          objv_tracker, refresh_version);
-  if (r < 0) {
-    return r;
-  }
-
-  if (pinfo) {
-    *pinfo = source.user_info;
-  }
-
-  return 0;
-}
-
-int RGWSI_User::User::SetOp::exec()
+int RGWSI_User::read_user_info(RGWSI_MetaBackend::Context *ctx,
+                               RGWUserInfo *info,
+                               RGWObjVersionTracker * const objv_tracker,
+                               real_time * const pmtime,
+                               rgw_cache_entry_info * const cache_info,
+                               map<string, bufferlist> * const pattrs,
+                               optional_yield y)
 {
-  int r = source.svc.user->store_user_info(source.user_info,
-                                           exclusive,
-                                           objv_tracker,
-                                           mtime, pattrs);
-  if (r < 0) {
-    return r;
-  }
-
-  return 0;
-}
-
-int RGWSI_User::read_user_info_meta_entry(RGWSI_MetaBackend::Context *ctx,
-                                          string& entry,
-                                          RGWUserInfo& info,
-                                          RGWObjVersionTracker * const objv_tracker,
-                                          real_time * const pmtime,
-                                          rgw_cache_entry_info * const cache_info,
-                                          map<string, bufferlist> * const pattrs) {
+#warning cache_info?
   bufferlist bl;
   RGWUID user_id;
 
-  RGWSI_MBSObj_GetParams params = {
-    pmtime,
-    std::nullopt, /* _bl */
-    &bl,
-    pattrs,
-    nullptr, /* cache_info */
-  };
-  int ret = svc.meta_be->get_entry(ctx, params, objv_tracker);
+  RGWSI_MBSObj_GetParams params(&bl, pattrs, pmtime);
+
+  int ret = svc.meta_be->get_entry(ctx, params, objv_tracker, y);
   if (ret < 0) {
     return ret;
   }
@@ -128,12 +71,13 @@ int RGWSI_User::read_user_info_meta_entry(RGWSI_MetaBackend::Context *ctx,
   auto iter = bl.cbegin();
   try {
     decode(user_id, iter);
-    if (User::get_meta_key(user_id.user_id).compare(entry) != 0) {
-      lderr(svc.meta_be->ctx())  << "ERROR: rgw_get_user_info_by_uid(): user id mismatch: " << User::get_meta_key(user_id.user_id) << " != " << entry << dendl;
+    auto meta_key = get_meta_key(user_id.user_id);
+    if (meta_key != ctx->key) {
+      lderr(svc.meta_be->ctx())  << "ERROR: rgw_get_user_info_by_uid(): user id mismatch: " << meta_key << " != " << ctx->key << dendl;
       return -EIO;
     }
     if (!iter.end()) {
-      decode(info, iter);
+      decode(*info, iter);
     }
   } catch (buffer::error& err) {
     ldout(svc.meta_be->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl;
@@ -143,77 +87,52 @@ int RGWSI_User::read_user_info_meta_entry(RGWSI_MetaBackend::Context *ctx,
   return 0;
 }
 
-int RGWSI_User::read_user_info(const rgw_user& user,
-                               RGWUserInfo *info,
-                               real_time *pmtime,
-                               map<string, bufferlist> *pattrs,
-                               RGWObjVersionTracker *objv_tracker,
-                               rgw_cache_entry_info *cache_info)
+class PutOperation
 {
-#warning cache?
-  string key = User::get_meta_key(user);
-  RGWUserMetadataObject *meta;
-  int ret = user_meta_handler->get(key, (RGWMetadataObject **)&meta);
-  if (ret < 0) {
-    return ret;
-  }
-
-  auto& uci = meta->get_uci();
-
-  if (info) {
-    *info = std::move(uci.info);
-  }
-
-  if (pmtime) {
-    *pmtime = meta->get_mtime();
-  }
-
-  if (objv_tracker) {
-    objv_tracker->read_version = meta->get_version();
-  }
-
-  delete meta;
-
-  return 0;
-}
-
-class RGWMetaPut_User
-{
-  RGWSI_MetaBackend::Context *ctx;
+  RGWSI_User::Svc& svc;
+  RGWSI_MetaBackend_SObj::Context_SObj *ctx;
   RGWUID ui;
-  string& entry;
   RGWUserInfo& info;
   RGWUserInfo *old_info;
   RGWObjVersionTracker *objv_tracker;
   real_time& mtime;
   bool exclusive;
   map<string, bufferlist> *pattrs;
-  
-  RGWMetaPut_User(RGWSI_MetaBackend::Context *ctx,
-                  string& entry,
-                  RGWUserInfo& info,
-                  RGWUserInfo *old_info,
-                  RGWObjVersionTracker *objv_tracker,
-                  real_time& mtime,
-                  bool exclusive,
-                  map<string, bufferlist> *pattrs) :
-      ctx(ctx), entry(entry),
-      info(info), old_info(old_info),
+  RGWObjVersionTracker ot;
+  string err_msg;
+  optional_yield y;
+
+  void set_err_msg(string msg) {
+    if (!err_msg.empty()) {
+      err_msg = std::move(msg);
+    }
+  }
+
+public:  
+  PutOperation(RGWSI_User::Svc& svc,
+               RGWSI_MetaBackend::Context *_ctx,
+               RGWUserInfo& info,
+               RGWUserInfo *old_info,
+               RGWObjVersionTracker *objv_tracker,
+               real_time& mtime,
+               bool exclusive,
+               map<string, bufferlist> *pattrs,
+               optional_yield _y) :
+      svc(svc), info(info), old_info(old_info),
       objv_tracker(objv_tracker), mtime(mtime),
-      exclusive(exclusive), pattrs(pattrs) {
+      exclusive(exclusive), pattrs(pattrs), y(_y) {
+    ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
     ui.user_id = info.user_id;
   }
 
   int prepare() {
-    RGWObjVersionTracker ot;
-
     if (objv_tracker) {
       ot = *objv_tracker;
     }
 
     if (ot.write_version.tag.empty()) {
       if (ot.read_version.tag.empty()) {
-        ot.generate_new_write_ver(store->ctx());
+        ot.generate_new_write_ver(svc.meta_be->ctx());
       } else {
         ot.write_version = ot.read_version;
         ot.write_version.ver++;
@@ -227,28 +146,24 @@ class RGWMetaPut_User
       RGWAccessKey& k = iter->second;
       /* check if swift mapping exists */
       RGWUserInfo inf;
-#warning this needs to change to use svc.sysobj
-      int r = do_get_user_info_by_swift(meta_be, ctx, k.id, inf);
+      int r = svc.user->get_user_info_by_swift(ctx, k.id, inf, nullptr, nullptr);
       if (r >= 0 && inf.user_id.compare(info.user_id) != 0) {
-        ldout(store->ctx(), 0) << "WARNING: can't store user info, swift id (" << k.id
+        ldout(svc.meta_be->ctx(), 0) << "WARNING: can't store user info, swift id (" << k.id
           << ") already mapped to another user (" << info.user_id << ")" << dendl;
         return -EEXIST;
       }
     }
 
-    if (!info.access_keys.empty()) {
-      /* check if access keys already exist */
+    /* check if access keys already exist */
+    for (auto iter = info.access_keys.begin(); iter != info.access_keys.end(); ++iter) {
+      if (old_info && old_info->access_keys.count(iter->first) != 0)
+        continue;
+      RGWAccessKey& k = iter->second;
       RGWUserInfo inf;
-      map<string, RGWAccessKey>::iterator iter = info.access_keys.begin();
-      for (; iter != info.access_keys.end(); ++iter) {
-        RGWAccessKey& k = iter->second;
-        if (old_info && old_info->access_keys.count(iter->first) != 0)
-          continue;
-        int r = do_get_user_info_by_access_key(meta_be, ctx, k.id, inf);
-        if (r >= 0 && inf.user_id.compare(info.user_id) != 0) {
-          ldout(store->ctx(), 0) << "WARNING: can't store user info, access key already mapped to another user" << dendl;
-          return -EEXIST;
-        }
+      int r = svc.user->get_user_info_by_access_key(ctx, k.id, &inf, nullptr, nullptr, y);
+      if (r >= 0 && inf.user_id.compare(info.user_id) != 0) {
+        ldout(svc.meta_be->ctx(), 0) << "WARNING: can't store user info, access key already mapped to another user" << dendl;
+        return -EEXIST;
       }
     }
 
@@ -260,7 +175,9 @@ class RGWMetaPut_User
     encode(ui, data_bl);
     encode(info, data_bl);
 
-    int ret = svc.meta_be->put_entry(ctx, data_bl, exclusive, &ot, mtime, pattrs);
+    RGWSI_MBSObj_PutParams params(data_bl, pattrs, mtime, exclusive);
+
+    int ret = svc.meta_be->put_entry(ctx, params, &ot);
     if (ret < 0)
       return ret;
 
@@ -270,31 +187,30 @@ class RGWMetaPut_User
   int complete() {
     int ret;
 
+    bufferlist link_bl;
+    encode(ui, link_bl);
+
+    auto& obj_ctx = *ctx->obj_ctx;
+
     if (!info.user_email.empty()) {
       if (!old_info ||
           old_info->user_email.compare(info.user_email) != 0) { /* only if new index changed */
-        bufferlist link_bl;
-        encode(ui, link_bl);
-
-        ret = rgw_put_system_obj(store, store->svc.zone->get_zone_params().user_email_pool, info.user_email,
-                                 link_bl, exclusive, NULL, real_time());
+        ret = rgw_put_system_obj(obj_ctx, svc.zone->get_zone_params().user_email_pool, info.user_email,
+                                 link_bl, exclusive, NULL, real_time(), y);
         if (ret < 0)
           return ret;
       }
     }
 
-    if (!info.access_keys.empty()) {
-      map<string, RGWAccessKey>::iterator iter = info.access_keys.begin();
-      for (; iter != info.access_keys.end(); ++iter) {
-        RGWAccessKey& k = iter->second;
-        if (old_info && old_info->access_keys.count(iter->first) != 0)
-          continue;
+    for (auto iter = info.access_keys.begin(); iter != info.access_keys.end(); ++iter) {
+      RGWAccessKey& k = iter->second;
+      if (old_info && old_info->access_keys.count(iter->first) != 0)
+        continue;
 
-        ret = rgw_put_system_obj(store, store->svc.zone->get_zone_params().user_keys_pool, k.id,
-                                 link_bl, exclusive, NULL, real_time());
-        if (ret < 0)
-          return ret;
-      }
+      ret = rgw_put_system_obj(obj_ctx, svc.zone->get_zone_params().user_keys_pool, k.id,
+                               link_bl, exclusive, NULL, real_time(), y);
+      if (ret < 0)
+        return ret;
     }
 
     map<string, RGWAccessKey>::iterator siter;
@@ -303,33 +219,320 @@ class RGWMetaPut_User
       if (old_info && old_info->swift_keys.count(siter->first) != 0)
         continue;
 
-      ret = rgw_put_system_obj(store, store->svc.zone->get_zone_params().user_swift_pool, k.id,
-                               link_bl, exclusive, NULL, real_time());
+      ret = rgw_put_system_obj(obj_ctx, svc.zone->get_zone_params().user_swift_pool, k.id,
+                               link_bl, exclusive, NULL, real_time(), y);
       if (ret < 0)
         return ret;
     }
 
+    if (old_info) {
+      ret = remove_old_indexes(*old_info, info, y);
+      if (ret < 0) {
+        return ret;
+      }
+    }
+
+    return 0;
+  }
+
+  int remove_old_indexes(RGWUserInfo& old_info, RGWUserInfo& new_info, optional_yield y) {
+    int ret;
+
+    if (!old_info.user_id.empty() &&
+        old_info.user_id != new_info.user_id) {
+      if (old_info.user_id.tenant != new_info.user_id.tenant) {
+        ldout(svc.user->ctx(), 0) << "ERROR: tenant mismatch: " << old_info.user_id.tenant << " != " << new_info.user_id.tenant << dendl;
+        return -EINVAL;
+      }
+      ret = svc.user->remove_uid_index(ctx, old_info, nullptr, y);
+      if (ret < 0 && ret != -ENOENT) {
+        set_err_msg("ERROR: could not remove index for uid " + old_info.user_id.to_str());
+        return ret;
+      }
+    }
+
+    if (!old_info.user_email.empty() &&
+        old_info.user_email.compare(new_info.user_email) != 0) {
+      ret = svc.user->remove_email_index(ctx, old_info.user_email, y);
+      if (ret < 0 && ret != -ENOENT) {
+        set_err_msg("ERROR: could not remove index for email " + old_info.user_email);
+        return ret;
+      }
+    }
+
+    map<string, RGWAccessKey>::iterator old_iter;
+    for (old_iter = old_info.swift_keys.begin(); old_iter != old_info.swift_keys.end(); ++old_iter) {
+      RGWAccessKey& swift_key = old_iter->second;
+      map<string, RGWAccessKey>::iterator new_iter = new_info.swift_keys.find(swift_key.id);
+      if (new_iter == new_info.swift_keys.end()) {
+        ret = svc.user->remove_swift_name_index(ctx, swift_key.id, y);
+        if (ret < 0 && ret != -ENOENT) {
+          set_err_msg("ERROR: could not remove index for swift_name " + swift_key.id);
+          return ret;
+        }
+      }
+    }
+
     return 0;
   }
+
+  const string& get_err_msg() {
+    return err_msg;
+  }
 };
 
-int RGWSI_User::store_user_info(RGWUserInfo& user_info, bool exclusive,
-                                map<string, bufferlist>& attrs,
+int RGWSI_User::store_user_info(RGWSI_MetaBackend::Context *ctx,
+                                RGWUserInfo& info,
+                                RGWUserInfo *old_info,
                                 RGWObjVersionTracker *objv_tracker,
-                                real_time mtime)
+                                real_time& mtime,
+                                bool exclusive,
+                                map<string, bufferlist> *attrs,
+                                optional_yield y)
 {
-  string entry = User::get_meta_key(user);
-  auto apply_type = (exclusive ? APPLY_EXCLUSIVE : APPLY_ALWAYS);
-  RGWUserCompleteInfo bci{user_info, attrs};
-  RGWUserMetadataObject mdo(bci, objv_tracker->write_version, mtime);
-  return user_meta_handler->put(entry, &mdo, *objv_tracker, apply_type);
+  PutOperation op(svc, ctx,
+                  info, old_info,
+                  objv_tracker,
+                  mtime, exclusive,
+                  attrs,
+                  y);
+
+  int r = op.prepare();
+  if (r < 0) {
+    return r;
+  }
+
+  r = op.put();
+  if (r < 0) {
+    return r;
+  }
+
+  r = op.complete();
+  if (r < 0) {
+    return r;
+  }
+
+  return 0;
 }
 
-int RGWSI_User::remove_user_info(const rgw_user& user,
-                                 RGWObjVersionTracker *objv_tracker)
+int RGWSI_User::remove_key_index(RGWSI_MetaBackend::Context *_ctx,
+                                 const RGWAccessKey& access_key,
+                                 optional_yield y)
 {
-  string entry = User::get_meta_key(user);
-  return user_handler->remove(entry, *objv_tracker);
+  RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
+  rgw_raw_obj obj(svc.zone->get_zone_params().user_keys_pool, access_key.id);
+  auto sysobj = ctx->obj_ctx->get_obj(obj);
+  return sysobj.wop().remove(y);
 }
 
+int RGWSI_User::remove_email_index(RGWSI_MetaBackend::Context *_ctx,
+                                   const string& email,
+                                   optional_yield y)
+{
+  if (email.empty()) {
+    return 0;
+  }
+  RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
+  rgw_raw_obj obj(svc.zone->get_zone_params().user_email_pool, email);
+  auto sysobj = ctx->obj_ctx->get_obj(obj);
+  return sysobj.wop().remove(y);
+}
+
+int RGWSI_User::remove_swift_name_index(RGWSI_MetaBackend::Context *_ctx, const string& swift_name,
+                                        optional_yield y)
+{
+  RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
+  rgw_raw_obj obj(svc.zone->get_zone_params().user_swift_pool, swift_name);
+  auto sysobj = ctx->obj_ctx->get_obj(obj);
+  return sysobj.wop().remove(y);
+}
+
+/**
+ * delete a user's presence from the RGW system.
+ * First remove their bucket ACLs, then delete them
+ * from the user and user email pools. This leaves the pools
+ * themselves alone, as well as any ACLs embedded in object xattrs.
+ */
+int RGWSI_User::remove_user_info(RGWSI_MetaBackend::Context *_ctx,
+                                 const RGWUserInfo& info,
+                                 RGWObjVersionTracker *objv_tracker,
+                                 optional_yield y)
+{
+  int ret;
+
+  auto cct = svc.meta_be->ctx();
+
+  auto kiter = info.access_keys.begin();
+  for (; kiter != info.access_keys.end(); ++kiter) {
+    ldout(cct, 10) << "removing key index: " << kiter->first << dendl;
+    ret = remove_key_index(_ctx, kiter->second, y);
+    if (ret < 0 && ret != -ENOENT) {
+      ldout(cct, 0) << "ERROR: could not remove " << kiter->first << " (access key object), should be fixed (err=" << ret << ")" << dendl;
+      return ret;
+    }
+  }
+
+  auto siter = info.swift_keys.begin();
+  for (; siter != info.swift_keys.end(); ++siter) {
+    auto& k = siter->second;
+    ldout(cct, 10) << "removing swift subuser index: " << k.id << dendl;
+    /* check if swift mapping exists */
+    ret = remove_swift_name_index(_ctx, k.id, y);
+    if (ret < 0 && ret != -ENOENT) {
+      ldout(cct, 0) << "ERROR: could not remove " << k.id << " (swift name object), should be fixed (err=" << ret << ")" << dendl;
+      return ret;
+    }
+  }
+
+  ldout(cct, 10) << "removing email index: " << info.user_email << dendl;
+  ret = remove_email_index(_ctx, info.user_email, y);
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "ERROR: could not remove email index object for "
+        << info.user_email << ", should be fixed (err=" << ret << ")" << dendl;
+    return ret;
+  }
+
+  string buckets_obj_id = get_buckets_oid(info.user_id);
+  rgw_raw_obj uid_bucks(svc.zone->get_zone_params().user_uid_pool, buckets_obj_id);
+  ldout(cct, 10) << "removing user buckets index" << dendl;
+  RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
+  auto sysobj = ctx->obj_ctx->get_obj(uid_bucks);
+  ret = sysobj.wop().remove(y);
+  if (ret < 0 && ret != -ENOENT) {
+    ldout(cct, 0) << "ERROR: could not remove " << info.user_id << ":" << uid_bucks << ", should be fixed (err=" << ret << ")" << dendl;
+    return ret;
+  }
+
+  ret = remove_uid_index(ctx, info, objv_tracker, y);
+  if (ret < 0 && ret != -ENOENT) {
+    return ret;
+  }
+
+  return 0;
+}
+
+int RGWSI_User::remove_uid_index(RGWSI_MetaBackend::Context *ctx, const RGWUserInfo& user_info, RGWObjVersionTracker *objv_tracker,
+                                 optional_yield y)
+{
+  ldout(cct, 10) << "removing user index: " << user_info.user_id << dendl;
+
+  RGWSI_MBSObj_RemoveParams params;
+#warning need mtime?
+#if 0
+  params.mtime = user_info.mtime;
+#endif
+  int ret = svc.meta_be->remove_entry(ctx, params, objv_tracker, y);
+  if (ret < 0 && ret != -ENOENT && ret  != -ECANCELED) {
+    string key;
+    user_info.user_id.to_str(key);
+    rgw_raw_obj uid_obj(svc.zone->get_zone_params().user_uid_pool, key);
+    ldout(cct, 0) << "ERROR: could not remove " << user_info.user_id << ":" << uid_obj << ", should be fixed (err=" << ret << ")" << dendl;
+    return ret;
+  }
+
+  return 0;
+}
+
+int RGWSI_User::get_user_info_from_index(RGWSI_MetaBackend::Context *_ctx,
+                                         const string& key,
+                                         const rgw_pool& pool,
+                                         RGWUserInfo *info,
+                                         RGWObjVersionTracker * const objv_tracker,
+                                         real_time * const pmtime,
+                                         optional_yield y)
+{
+  RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
+
+#warning uinfo_cache needs to add index to lookup
+  if (auto e = uinfo_cache->find(key)) {
+    *info = e->info;
+    if (objv_tracker)
+      *objv_tracker = e->objv_tracker;
+    if (pmtime)
+      *pmtime = e->mtime;
+    return 0;
+  }
+
+  user_info_cache_entry e;
+  bufferlist bl;
+  RGWUID uid;
+
+  int ret = rgw_get_system_obj(*ctx->obj_ctx, pool, key, bl, nullptr, &e.mtime, y);
+  if (ret < 0)
+    return ret;
+
+  rgw_cache_entry_info cache_info;
+
+  auto iter = bl.cbegin();
+  try {
+    decode(uid, iter);
+
+    int ret = read_user_info(ctx->clone(get_meta_key(uid.user_id)),
+                             &e.info, &e.objv_tracker, nullptr, &cache_info, nullptr, y);
+    if (ret < 0) {
+      return ret;
+    }
+  } catch (buffer::error& err) {
+    ldout(svc.meta_be->ctx(), 0) << "ERROR: failed to decode user info, caught buffer::error" << dendl;
+    return -EIO;
+  }
+
+  uinfo_cache->put(svc.cache, key, &e, { &cache_info });
+
+  *info = e.info;
+  if (objv_tracker)
+    *objv_tracker = e.objv_tracker;
+  if (pmtime)
+    *pmtime = e.mtime;
+
+  return 0;
+}
+
+/**
+ * Given an email, finds the user info associated with it.
+ * returns: 0 on success, -ERR# on failure (including nonexistence)
+ */
+int RGWSI_User::get_user_info_by_email(RGWSI_MetaBackend::Context *ctx,
+                                       const string& email, RGWUserInfo *info,
+                                       RGWObjVersionTracker *objv_tracker,
+                                       real_time *pmtime,
+                                       optional_yield y)
+{
+  return get_user_info_from_index(ctx, email, svc.zone->get_zone_params().user_email_pool,
+                                  info, objv_tracker, pmtime, y);
+}
+
+/**
+ * Given an swift username, finds the user_info associated with it.
+ * returns: 0 on success, -ERR# on failure (including nonexistence)
+ */
+int RGWSI_User::get_user_info_by_swift(RGWSI_MetaBackend::Context *ctx,
+                                       const string& swift_name,
+                                       RGWUserInfo *info,        /* out */
+                                       RGWObjVersionTracker * const objv_tracker,
+                                       real_time * const pmtime,
+                                       optional_yield y)
+{
+  return get_user_info_from_index(ctx,
+                                  swift_name,
+                                  svc.zone->get_zone_params().user_swift_pool,
+                                  info, objv_tracker, pmtime, y);
+}
+
+/**
+ * Given an access key, finds the user info associated with it.
+ * returns: 0 on success, -ERR# on failure (including nonexistence)
+ */
+int RGWSI_User::get_user_info_by_access_key(RGWSI_MetaBackend::Context *ctx,
+                                            const std::string& access_key,
+                                            RGWUserInfo *info,
+                                            RGWObjVersionTracker* objv_tracker,
+                                            real_time *pmtime,
+                                            optional_yield y)
+{
+  return get_user_info_from_index(ctx,
+                                  access_key,
+                                  svc.zone->get_zone_params().user_keys_pool,
+                                  info, objv_tracker, pmtime, y);
+}
 
index 68b415aa8ed43e60ed5446a61806a7440439c5af..0cd0f3ea361cd11d8cbb539207b83ef679575330 100644 (file)
@@ -36,16 +36,7 @@ class RGWChainedCacheImpl;
 class RGWSI_User : public RGWServiceInstance
 {
   friend class User;
-
-  struct Svc {
-    RGWSI_User *user{nullptr};
-    RGWSI_Zone *zone{nullptr};
-    RGWSI_SysObj *sysobj{nullptr};
-    RGWSI_SysObj_Cache *cache{nullptr};
-    RGWSI_Meta *meta{nullptr};
-    RGWSI_MetaBackend *meta_be{nullptr};
-    RGWSI_SyncModules *sync_modules{nullptr};
-  } svc;
+  friend class PutOperation;
 
   RGWMetadataHandler *user_meta_handler;
 
@@ -58,24 +49,31 @@ class RGWSI_User : public RGWServiceInstance
   using RGWChainedCacheImpl_user_info_cache_entry = RGWChainedCacheImpl<user_info_cache_entry>;
   unique_ptr<RGWChainedCacheImpl_user_info_cache_entry> uinfo_cache;
 
-  int read_user_info_meta(RGWSI_MetaBackend::Context *ctx,
-                          string& entry,
-                          RGWUserInfo& info,
-                          RGWObjVersionTracker * const objv_tracker,
-                          real_time * const pmtime,
-                          rgw_cache_entry_info * const cache_info,
-                          map<string, bufferlist> * const pattrs);
-  int store_user_info_meta(RGWSI_MetaBackend::Context *ctx,
-                           string& entry,
-                           RGWUserInfo& info,
-                           RGWUserInfo *old_info,
-                           RGWObjVersionTracker *objv_tracker,
-                           real_time& mtime,
-                           bool exclusive,
-                           map<string, bufferlist> *pattrs);
+  int get_user_info_from_index(RGWSI_MetaBackend::Context *ctx,
+                               const string& key,
+                               const rgw_pool& pool,
+                               RGWUserInfo *info,
+                               RGWObjVersionTracker * const objv_tracker,
+                               real_time * const pmtime);
+
+  int remove_uid_index(RGWSI_MetaBackend::Context *ctx, const RGWUserInfo& user_info, RGWObjVersionTracker *objv_tracker);
+
+  int remove_key_index(RGWSI_MetaBackend::Context *ctx, const RGWAccessKey& access_key);
+  int remove_email_index(RGWSI_MetaBackend::Context *ctx, const string& email);
+  int remove_swift_name_index(RGWSI_MetaBackend::Context *ctx, const string& swift_name);
 
   int do_start() override;
 public:
+  struct Svc {
+    RGWSI_User *user{nullptr};
+    RGWSI_Zone *zone{nullptr};
+    RGWSI_SysObj *sysobj{nullptr};
+    RGWSI_SysObj_Cache *cache{nullptr};
+    RGWSI_Meta *meta{nullptr};
+    RGWSI_MetaBackend *meta_be{nullptr};
+    RGWSI_SyncModules *sync_modules{nullptr};
+  } svc;
+
   RGWSI_User(CephContext *cct);
   ~RGWSI_User();
 
@@ -84,6 +82,16 @@ public:
             RGWSI_MetaBackend *_meta_be_svc,
            RGWSI_SyncModules *_sync_modules);
 
+  static string get_meta_key(const rgw_user& user) {
+    return user.to_str();
+  }
+
+  static string get_buckets_oid(const rgw_user& user_id) {
+#define RGW_BUCKETS_OID_SUFFIX ".buckets"
+    return user_id.to_str() + RGW_BUCKETS_OID_SUFFIX;
+  }
+
+#if 0
   class User {
     friend class Op;
 
@@ -110,16 +118,11 @@ public:
       return user_info;
     }
 
-    static string get_meta_key(const rgw_user& user) {
-      return user.to_str();
-    }
-
     struct GetOp {
       User& source;
 
       ceph::real_time *pmtime{nullptr};
       map<string, bufferlist> *pattrs{nullptr};
-      boost::optional<obj_version> refresh_version;
       RGWUserInfo *pinfo{nullptr};
       RGWObjVersionTracker *objv_tracker{nullptr};
 
@@ -134,11 +137,6 @@ public:
         return *this;
       }
 
-      GetOp& set_refresh_version(const obj_version& rf) {
-        refresh_version = rf;
-        return *this;
-      }
-
       GetOp& set_pinfo(RGWUserInfo *_pinfo) {
         pinfo = _pinfo;
         return *this;
@@ -199,18 +197,48 @@ public:
 
   User user(RGWSysObjectCtx& _ctx,
             const rgw_user& _user);
+#endif
+
+  /* base svc_user interfaces */
 
-  int read_user_info(const rgw_user& user,
+  int read_user_info(RGWSI_MetaBackend::Context *ctx,
                      RGWUserInfo *info,
-                     real_time *pmtime,
-                     map<string, bufferlist> *pattrs,
-                     RGWObjVersionTracker *objv_tracker,
-                     rgw_cache_entry_info *cache_info);
-  int store_user_info(RGWUserInfo& user_info, bool exclusive,
-                      map<string, bufferlist>& attrs,
+                     RGWObjVersionTracker * const objv_tracker,
+                     real_time * const pmtime,
+                     rgw_cache_entry_info * const cache_info,
+                     map<string, bufferlist> * const pattrs,
+                     optional_yield y);
+
+  int store_user_info(RGWSI_MetaBackend::Context *ctx,
+                      RGWUserInfo& info,
+                      RGWUserInfo *old_info,
                       RGWObjVersionTracker *objv_tracker,
-                      real_time mtime);
-  int remove_user_info(const rgw_user& user,
-                       RGWObjVersionTracker *objv_tracker);
+                      real_time& mtime,
+                      bool exclusive,
+                      map<string, bufferlist> *attrs,
+                      optional_yield y);
+
+  int remove_user_info(RGWSI_MetaBackend::Context *ctx,
+                       const RGWUserInfo& info,
+                       RGWObjVersionTracker *objv_tracker,
+                       optional_yield y);
+
+  int get_user_info_by_email(RGWSI_MetaBackend::Context *ctx,
+                             const string& email, RGWUserInfo *info,
+                             RGWObjVersionTracker *objv_tracker,
+                             real_time *pmtime,
+                             optional_yield y);
+  int get_user_info_by_swift(RGWSI_MetaBackend::Context *ctx,
+                             const string& swift_name,
+                             RGWUserInfo *info,        /* out */
+                             RGWObjVersionTracker * const objv_tracker,
+                             real_time * const pmtime,
+                             optional_yield y);
+  int get_user_info_by_access_key(RGWSI_MetaBackend::Context *ctx,
+                                  const std::string& access_key,
+                                  RGWUserInfo *info,
+                                  RGWObjVersionTracker* objv_tracker,
+                                  real_time *pmtime,
+                                  optional_yield y);
 };