JSONDecoder::decode_json("attrs", attrs, obj);
}
-class RGW_MB_Handler_Module_Bucket : public RGWSI_MBSObj_Handler_Module {
- RGWSI_Zone *zone_svc;
-public:
- RGW_MB_Handler_Module_Bucket(RGWSI_Zone *_zone_svc) : zone_svc(_zone_svc) {}
-
- void get_pool_and_oid(const string& key, rgw_pool *pool, string *oid) override {
- *oid = key;
- *pool = zone_svc->get_zone_params().domain_root;
- }
-};
-
class RGWBucketMetadataHandler : public RGWMetadataHandler {
RGWSI_MetaBackend_Handler *be_handler{nullptr};
public:
optional_yield y,
RGWMDLogSyncType type) override;
- struct list_keys_info {
- RGWRados *store;
- RGWListRawObjsCtx ctx;
- };
-
int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker,
optional_yield y) {
RGWUserInfo info;
int list_keys_init(const string& marker, void **phandle) override
{
- auto info = std::make_unique<list_keys_info>();
-
- info->store = store;
+ std::unique_ptr<RGWSI_MetaBackend_Handler::Op> op(be_handler->alloc_op());
- int ret = store->list_raw_objects_init(store->svc.zone->get_zone_params().user_uid_pool, marker,
- &info->ctx);
+ int ret = op->list_init(marker);
if (ret < 0) {
return ret;
}
- *phandle = (void *)info.release();
+ *phandle = (void *)op.release();
return 0;
}
int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) override {
- list_keys_info *info = static_cast<list_keys_info *>(handle);
-
- string no_filter;
-
- keys.clear();
+ auto op = static_cast<RGWSI_MetaBackend_Handler::Op *>(handle);
- RGWRados *store = info->store;
-
- list<string> unfiltered_keys;
-
- int ret = store->list_raw_objects_next(no_filter, max, info->ctx,
- unfiltered_keys, truncated);
- if (ret < 0 && ret != -ENOENT)
- return ret;
+ int ret = op->list_next(max, &keys, truncated);
+ if (ret < 0 && ret != -ENOENT) {
+ return ret;
+ }
if (ret == -ENOENT) {
- if (truncated)
+ if (truncated) {
*truncated = false;
- return 0;
- }
-
- // now filter out the buckets entries
- list<string>::iterator iter;
- for (iter = unfiltered_keys.begin(); iter != unfiltered_keys.end(); ++iter) {
- string& k = *iter;
-
- if (k.find(".buckets") == string::npos) {
- keys.push_back(k);
}
+ return 0;
}
return 0;
}
void list_keys_complete(void *handle) override {
- list_keys_info *info = static_cast<list_keys_info *>(handle);
- delete info;
+ auto op = static_cast<RGWSI_MetaBackend_Handler::Op *>(handle);
+ delete op;
}
string get_marker(void *handle) override {
- list_keys_info *info = static_cast<list_keys_info *>(handle);
- return info->store->list_raw_objs_get_cursor(info->ctx);
+ auto op = static_cast<RGWSI_MetaBackend_Handler::Op *>(handle);
+ string marker;
+ int r = op->list_get_marker(&marker);
+ if (r < 0) {
+ lderr(svc.user->ctx(), 0) << "ERROR: " << __func__ << "(): list_get_marker() returned: r=" << r << dendl;
+ /* not much else to do */
+ }
+
+ return marker;
}
};
class RGWSI_Bucket_Module : public RGWSI_MBSObj_Handler_Module {
RGWSI_Bucket::Svc& svc;
+
+ const string prefix;
public:
RGWSI_Bucket_Module(RGWSI_Bucket::Svc& _svc) : svc(_svc) {}
void get_pool_and_oid(const string& key, rgw_pool *pool, string *oid) override {
- *oid = key;
- *pool = svc.zone->get_zone_params().domain_root;
+ if (pool) {
+ *pool = svc.zone->get_zone_params().domain_root;
+ }
+ if (oid) {
+ *oid = key;
+ }
+ }
+
+ const string& get_oid_prefix() override {
+ return prefix;
+ }
+
+ bool is_valid_oid(const string& oid) override {
+ return (!oid.empty() && oid[0] != '.');
+ }
+
+ string key_to_oid(const string& key) override {
+ return key;
+ }
+
+ string oid_to_key(const string& oid) override {
+ /* should have been called after is_valid_oid(),
+ * so no need to check for validity */
+ return oid;
}
};
class RGWSI_BucketInstance_Module : public RGWSI_MBSObj_Handler_Module {
RGWSI_Bucket::Svc& svc;
+
+ const string prefix;
public:
- RGWSI_BucketInstance_Module(RGWSI_Bucket::Svc& _svc) : svc(_svc) {}
+ RGWSI_BucketInstance_Module(RGWSI_Bucket::Svc& _svc) : svc(_svc), prefix(RGW_BUCKET_INSTANCE_MD_PREFIX) {}
-#warning get_hash_key?
-#if 0
- /*
- * hash entry for mdlog placement. Use the same hash key we'd have for the bucket entry
- * point, so that the log entries end up at the same log shard, so that we process them
- * in order
- */
- void get_hash_key(const string& section, const string& key, string& hash_key) override {
- string k;
- int pos = key.find(':');
- if (pos < 0)
- k = key;
- else
- k = key.substr(0, pos);
- hash_key = "bucket:" + k;
+ void get_pool_and_oid(const string& key, rgw_pool *pool, string *oid) override {
+ if (pool) {
+ *pool = svc.zone->get_zone_params().domain_root;
+ }
+ if (oid) {
+ *oid = key_to_oid(key);
+ }
}
-#endif
- void get_pool_and_oid(const string& key, rgw_pool *pool, string *oid) override {
- *oid = RGW_BUCKET_INSTANCE_MD_PREFIX + key;
- *pool = svc.zone->get_zone_params().domain_root;
+ const string& get_oid_prefix() override {
+ return prefix;
+ }
+
+ bool is_valid_oid(const string& oid) override {
+ return (oid.compare(0, prefix.size(), RGW_BUCKET_INSTANCE_MD_PREFIX) == 0);
}
// 'tenant/' is used in bucket instance keys for sync to avoid parsing ambiguity
// with the existing instance[:shard] format. once we parse the shard, the / is
// replaced with a : to match the [tenant:]instance format
- void key_to_oid(string& key) override {
+ string key_to_oid(const string& key) override {
+ string oid = prefix + key;
+
// replace tenant/ with tenant:
- auto c = key.find('/');
+ auto c = oid.find('/', prefix.size());
if (c != string::npos) {
- key[c] = ':';
+ oid[c] = ':';
}
+
+ return oid;
}
// convert bucket instance oids back to the tenant/ format for metadata keys.
// it's safe to parse 'tenant:' only for oids, because they won't contain the
// optional :shard at the end
- void oid_to_key(string& oid) override {
+ string oid_to_key(const string& oid) override {
+ /* this should have been called after oid was checked for validity */
+
+ if (oid.size() < prefix.size()) { /* just sanity check */
+ return string();
+ }
+
+ string key = oid.substr(prefix.size());
+
// find first : (could be tenant:bucket or bucket:instance)
- auto c = oid.find(':');
+ auto c = key.find(':');
if (c != string::npos) {
// if we find another :, the first one was for tenant
- if (oid.find(':', c + 1) != string::npos) {
- oid[c] = '/';
+ if (key.find(':', c + 1) != string::npos) {
+ key[c] = '/';
}
}
+
+ return key;
+ }
+
+ /*
+ * hash entry for mdlog placement. Use the same hash key we'd have for the bucket entry
+ * point, so that the log entries end up at the same log shard, so that we process them
+ * in order
+ */
+ string get_hash_key(const string& section, const string& key) override {
+ string k = "bucket:";
+ int pos = key.find(':');
+ if (pos < 0)
+ k.append(key);
+ else
+ k.append(key.substr(0, pos));
+
+ return k;
}
};
});
}
+RGWSI_MetaBackend_Handler::Op *RGWSI_MetaBackend_Handler::alloc_op()
+{
+ return new Op_ManagedCtx(be);
+}
+
+RGWSI_MetaBackend_Handler::Op_ManagedCtx::Op_ManagedCtx(RGWSI_MetaBackend *_be) : Op(_be, _be->alloc_ctx())
+{
+ pctx.reset(ctx());
+}
+
virtual void init(RGWSI_MetaBackend_Handler *h) = 0;
};
+ virtual Context *alloc_ctx() = 0;
+
struct PutParams {
ceph::real_time mtime;
RGWObjVersionTracker *objv_tracker,
optional_yield y) = 0;
- virtual int list_init(const string& marker, void **phandle) = 0;
- virtual int list_next(void *handle, int max, std:::list<std::string>& keys, bool *truncated) = 0;
- virtual void list_complete(void *handle) = 0;
+ virtual int list_init(RGWSI_MetaBackend::Context *ctx, const string& marker) = 0;
+ virtual int list_next(RGWSI_MetaBackend::Context *ctx,
+ int max, list<string>& keys,
+ bool *truncated) = 0;
+ virtual int list_get_marker(RGWSI_MetaBackend::Context *ctx,
+ string *marker) = 0;
virtual int call(std::function<int(RGWSI_MetaBackend::Context *)> f) = 0;
RGWMDLogSyncType sync_mode) {
return be->remove(be_ctx, key, params, objv_tracker, sync_mode);
}
+
+ int list_init(const string& marker) {
+ return be->list_init(be_ctx, marker);
+ }
+ int list_next(int max, list<string>& keys,
+ bool *truncated) {
+ return be->list_next(max, keys, truncated);
+ }
+ int list_get_marker(string *marker) {
+ return be->list_get_marker(marker);
+ }
+ };
+
+ class Op_ManagedCtx : public Op {
+ std::unique_ptr<RGWSI_MetaBackend::Context> pctx;
+ public:
+ Op_ManagedCtx(RGWSI_MetaBackend *_be);
};
RGWSI_MetaBackend_Handler(RGWSI_MetaBackend *_be) : be(_be) {}
virtual ~RGWSI_MetaBackend_Handler() {}
virtual int call(std::function<int(Op *)> f);
+ virtual Op *alloc_op();
};
return new RGWSI_MetaBackend_Handler_SObj(this);
}
+RGWSI_MetaBackend_SObj::alloc_ctx()
+{
+ return new ctx(sysobj_svc);
+}
+
int RGWSI_MetaBackend_SObj::call(std::function<int(RGWSI_MetaBackend::Context *)> f)
{
RGWSI_MetaBackend_SObj::Context_SObj ctx(sysobj_svc);
.remove(params.y);
}
-int RGWSI_MetaBackend_SObj::list_init(const string& marker, void **phandle) override {
- auto info = std::make_unique<list_keys_info>();
+int RGWSI_MetaBackend_SObj::list_init(RGWSI_MetaBackend::Context *_ctx,
+ const string& marker)
+{
+ RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
- int ret = store->list_raw_objects_init(store->svc.zone->get_zone_params().domain_root, marker,
- &info->ctx);
- if (ret < 0) {
- return ret;
- }
- *phandle = (void *)info.release();
+ rgw_pool pool;
- return 0;
- }
+ string no_key;
+ ctx->module->get_pool_and_oid(no_key, &ctx->list.pool, nullptr);
-int RGWSI_MetaBackend_SObj::list_next(void *handle, int max, list<string>& keys, bool *truncated) override {
- list_keys_info *info = static_cast<list_keys_info *>(handle);
+ ctx->list.pool = sysobj_svc->get_pool(pool);
+ ctx->list.op = ctx->list.pool->op();
- string no_filter;
+ string prefix = ctx->module->get_prefix();
+ ctx->list.op->init(marker, prefix);
- keys.clear();
+ return 0;
+}
+
+int RGWSI_MetaBackend_SObj::list_next(RGWSI_MetaBackend::Context *_ctx,
+ int max, list<string>& keys,
+ bool *truncated)
+{
+ RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
- list<string> unfiltered_keys;
+ vector<string> oids;
- int ret = store->list_raw_objects_next(no_filter, max, info->ctx,
- unfiltered_keys, truncated);
+ int ret = ctx->list.op->get_next(max, &oids, truncated);
if (ret < 0 && ret != -ENOENT)
return ret;
if (ret == -ENOENT) {
return 0;
}
- constexpr int prefix_size = sizeof(RGW_BUCKET_INSTANCE_MD_PREFIX) - 1;
- // now filter in the relevant entries
- list<string>::iterator iter;
- for (iter = unfiltered_keys.begin(); iter != unfiltered_keys.end(); ++iter) {
- string& k = *iter;
+ auto module = ctx->module;
- if (k.compare(0, prefix_size, RGW_BUCKET_INSTANCE_MD_PREFIX) == 0) {
- auto oid = k.substr(prefix_size);
- rgw_bucket_instance_oid_to_key(oid);
- keys.emplace_back(std::move(oid));
+ for (auto& o : oids) {
+ if (!module->is_valid_oid(o)) {
+ continue;
}
+ keys.emplace_back(module->oid_to_key(o));
}
return 0;
}
-void RGWSI_MetaBackend_SObj::list_complete(void *handle) override {
- list_keys_info *info = static_cast<list_keys_info *>(handle);
- delete info;
-}
+int RGWSI_MetaBackend_SObj::list_get_marker(RGWSI_MetaBackend::Context *_ctx,
+ string *marker)
+{
+ RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
-string get_marker(void *handle) override {
- list_keys_info *info = static_cast<list_keys_info *>(handle);
- return info->store->list_raw_objs_get_cursor(info->ctx);
+ return ctx->list.op->get_marker(marker);
}
class RGWSI_MBSObj_Handler_Module : public RGWSI_MetaBackend::Module {
public:
- virtual void get_pool_and_oid(const string& key, rgw_pool *pool, string *oid) = 0;
- virtual void key_to_oid(string& key) {}
- virtual void oid_to_key(string& oid) {}
+ virtual void get_pool_and_oid(const std::string& key, rgw_pool *pool, std::string *oid) = 0;
+ virtual const std::string& get_oid_prefix() = 0;
+ virtual std::string key_to_oid(const std::string& key) = 0;
+ virtual bool is_valid_oid(const std::string& oid) = 0;
+ virtual std::string oid_to_key(const std::string& oid) = 0;
/* key to use for hashing entries for log shard placement */
- virtual void get_hash_key(const std::string& section, const std::string& key, std::string& hash_key) {
- hash_key = section + ":" + key;
+ virtual std::string get_hash_key(const std::string& section, const std::string& key) {
+ return section + ":" + key;
}
};
RGWSI_SysObj *sysobj_svc{nullptr};
RGWSI_MBSObj_Handler_Module *module{nullptr};
- optional<RGWSysObjectCtx> obj_ctx;
+ std::optional<RGWSysObjectCtx> obj_ctx;
+ struct _list {
+ std::optional<RGWSI_SysObj::Pool> pool;
+ std::optional<RGWSI_SysObj::Pool::Op> op;
+ } list;
Context_SObj(RGWSI_SysObj *_sysobj_svc) : sysobj_svc(_sysobj_svc) {}
RGWSI_MetaBackend::RemoveParams& params,
RGWObjVersionTracker *objv_tracker) override;
- int list_init(const string& marker, void **phandle) override;
- int list_next(void *handle, int max, std:::list<std::string>& keys, bool *truncated) override;
- void list_complete(void *handle) override;
+ int list_init(RGWSI_MetaBackend::Context *_ctx, const string& marker) override;
+ int list_next(RGWSI_MetaBackend::Context *_ctx,
+ int max, list<string>& keys,
+ bool *truncated) override;
+ int list_get_marker(RGWSI_MetaBackend::Context *ctx,
+ string *marker) override;
int call(std::function<int(RGWSI_MetaBackend::Context *)> f) override;
};
librados::Rados *rad = rados_svc->get_rados_handle();
return rad->watch_flush();
}
+
+int RGWSI_RADOS::Pool::List::get_marker(string *marker)
+{
+ if (!ctx.initialized) {
+ return -EINVAL;
+ }
+
+ *marker = ctx.iter.get_cursor().to_str();
+ return 0;
+}
int get_next(int max,
std::vector<string> *oids,
bool *is_truncated);
+
+ int get_marker(string *marker);
};
List op() {
return source.core_svc->pool_list_objects_next(ctx, max, oids, is_truncated);
}
+int RGWSI_SysObj::Pool::Op::get_marker(string *marker)
+{
+ return source.core_svc->pool_list_objects_get_marker(ctx, marker);
+}
+
int RGWSI_SysObj::Obj::OmapOp::get_all(std::map<string, bufferlist> *m,
optional_yield y)
{
int init(const std::string& marker, const std::string& prefix);
int get_next(int max, std::vector<string> *oids, bool *is_truncated);
+ int get_marker(string *marker);
};
int list_prefixed_objs(const std::string& prefix, std::vector<std::string> *result);
optional_yield y) override;
int read(RGWSysObjectCtxBase& obj_ctx,
- GetObjState& read_state,
+ RGWSI_SysObj_Obj_GetObjState& read_state,
RGWObjVersionTracker *objv_tracker,
const rgw_raw_obj& obj,
bufferlist *bl, off_t ofs, off_t end,
return oids->size();
}
+int RGWSI_SysObj_Core::pool_list_objects_get_marker(RGWSI_SysObj::Pool::ListCtx& _ctx,
+ string *marker)
+{
+ if (!_ctx.impl) {
+ return -EINVAL;
+ }
+
+ auto& ctx = static_cast<PoolListImplInfo&>(*_ctx.impl);
+ return ctx.op.get_marker(marker);
+}
vector<string> *oids,
bool *is_truncated);
+ virtual int pool_list_objects_get_marker(RGWSI_SysObj::Pool::ListCtx& _ctx,
+ string *marker);
+
/* wrappers */
int get_system_obj_state_impl(RGWSysObjectCtxBase *rctx,
const rgw_raw_obj& obj, RGWSysObjState **state,
class RGWSI_User_Module : public RGWSI_MBSObj_Handler_Module {
RGWSI_User::Svc& svc;
+
+ const string prefix;
public:
RGWSI_User_Module(RGWSI_User::Svc& _svc) : svc(_svc) {}
void get_pool_and_oid(const string& key, rgw_pool *pool, string *oid) override {
- *oid = key;
- *pool = svc.zone->get_zone_params().user_uid_pool;
+ if (pool) {
+ *pool = svc.zone->get_zone_params().user_uid_pool;
+ }
+ if (oid) {
+ *oid = key;
+ }
+ }
+
+ const string& get_oid_prefix() override {
+ return prefix;
+ }
+
+ bool is_valid_oid(const string& oid) override {
+ return true;
+ }
+
+ string key_to_oid(const string& key) override {
+ return key;
+ }
+
+ string oid_to_key(const string& oid) override {
+ return oid;
}
};