Merge pull request #36381 from dang/wip-dang-zipper-7

Zipper 7 - chop list items
This commit is contained in:
Daniel Gryniewicz 2020-08-19 09:50:58 -04:00 committed by GitHub
commit e88a413151
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 894 additions and 897 deletions

View File

@ -4,3 +4,4 @@ overrides:
client:
setuser: ceph
setgroup: ceph
debug rgw: 20

View File

@ -334,86 +334,6 @@ int rgw_remove_object(rgw::sal::RGWRadosStore *store, const RGWBucketInfo& bucke
return store->getRados()->delete_obj(rctx, bucket_info, obj, bucket_info.versioning_status());
}
/* xxx dang */
static int rgw_remove_bucket(rgw::sal::RGWRadosStore *store, rgw_bucket& bucket, bool delete_children, optional_yield y)
{
int ret;
map<RGWObjCategory, RGWStorageStats> stats;
std::vector<rgw_bucket_dir_entry> objs;
map<string, bool> common_prefixes;
RGWBucketInfo info;
string bucket_ver, master_ver;
ret = store->getRados()->get_bucket_info(store->svc(), bucket.tenant, bucket.name, info, NULL, null_yield);
if (ret < 0)
return ret;
ret = store->getRados()->get_bucket_stats(info, RGW_NO_SHARD, &bucket_ver, &master_ver, stats, NULL);
if (ret < 0)
return ret;
RGWRados::Bucket target(store->getRados(), info);
RGWRados::Bucket::List list_op(&target);
CephContext *cct = store->ctx();
list_op.params.list_versions = true;
list_op.params.allow_unordered = true;
bool is_truncated = false;
do {
objs.clear();
ret = list_op.list_objects(listing_max_entries, &objs, &common_prefixes,
&is_truncated, null_yield);
if (ret < 0)
return ret;
if (!objs.empty() && !delete_children) {
lderr(store->ctx()) << "ERROR: could not remove non-empty bucket " << bucket.name << dendl;
return -ENOTEMPTY;
}
for (const auto& obj : objs) {
rgw_obj_key key(obj.key);
ret = rgw_remove_object(store, info, bucket, key);
if (ret < 0 && ret != -ENOENT) {
return ret;
}
}
} while(is_truncated);
string prefix, delimiter;
ret = abort_bucket_multiparts(store, cct, info, prefix, delimiter);
if (ret < 0) {
return ret;
}
ret = store->ctl()->bucket->sync_user_stats(info.owner, info);
if ( ret < 0) {
dout(1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl;
}
RGWObjVersionTracker objv_tracker;
// if we deleted children above we will force delete, as any that
// remain is detrius from a prior bug
ret = store->getRados()->delete_bucket(info, objv_tracker, null_yield, !delete_children);
if (ret < 0) {
lderr(store->ctx()) << "ERROR: could not remove bucket " <<
bucket.name << dendl;
return ret;
}
ret = store->ctl()->bucket->unlink_bucket(info.owner, bucket, null_yield, false);
if (ret < 0) {
lderr(store->ctx()) << "ERROR: unable to remove user bucket information" << dendl;
}
return ret;
}
static int aio_wait(librados::AioCompletion *handle)
{
librados::AioCompletion *c = (librados::AioCompletion *)handle;
@ -851,32 +771,6 @@ int RGWBucket::set_quota(RGWBucketAdminOpState& op_state, std::string *err_msg)
return r;
}
int RGWBucket::remove(RGWBucketAdminOpState& op_state, optional_yield y, bool bypass_gc,
bool keep_index_consistent, std::string *err_msg)
{
bool delete_children = op_state.will_delete_children();
rgw_bucket bucket = op_state.get_bucket();
int ret;
if (bypass_gc) {
if (delete_children) {
ret = rgw_remove_bucket_bypass_gc(store, bucket, op_state.get_max_aio(), keep_index_consistent, y);
} else {
set_err_msg(err_msg, "purge objects should be set for gc to be bypassed");
return -EINVAL;
}
} else {
ret = rgw_remove_bucket(store, bucket, delete_children, y);
}
if (ret < 0) {
set_err_msg(err_msg, "unable to remove bucket" + cpp_strerror(-ret));
return ret;
}
return 0;
}
int RGWBucket::remove_object(RGWBucketAdminOpState& op_state, std::string *err_msg)
{
rgw_bucket bucket = op_state.get_bucket();
@ -1361,19 +1255,22 @@ int RGWBucketAdminOp::check_index(rgw::sal::RGWRadosStore *store, RGWBucketAdmin
}
int RGWBucketAdminOp::remove_bucket(rgw::sal::RGWRadosStore *store, RGWBucketAdminOpState& op_state,
optional_yield y, bool bypass_gc, bool keep_index_consistent)
optional_yield y, bool bypass_gc, bool keep_index_consistent)
{
RGWBucket bucket;
std::unique_ptr<rgw::sal::RGWBucket> bucket;
std::unique_ptr<rgw::sal::RGWUser> user = store->get_user(op_state.get_user_id());
int ret = bucket.init(store, op_state, y);
int ret = store->get_bucket(user.get(), user->get_tenant(), op_state.get_bucket_name(),
&bucket);
if (ret < 0)
return ret;
std::string err_msg;
ret = bucket.remove(op_state, y, bypass_gc, keep_index_consistent, &err_msg);
if (!err_msg.empty()) {
lderr(store->ctx()) << "ERROR: " << err_msg << dendl;
}
if (bypass_gc)
ret = rgw_remove_bucket_bypass_gc(store, bucket->get_key(), op_state.get_max_aio(), keep_index_consistent, y);
else
ret = bucket->remove_bucket(op_state.will_delete_children(), string(), string(),
false, nullptr, y);
return ret;
}

View File

@ -353,7 +353,6 @@ public:
map<RGWObjCategory, RGWStorageStats>& calculated_stats,
std::string *err_msg = NULL);
int remove(RGWBucketAdminOpState& op_state, optional_yield y, bool bypass_gc = false, bool keep_index_consistent = true, std::string *err_msg = NULL);
int link(RGWBucketAdminOpState& op_state, optional_yield y,
map<string, bufferlist>& attrs, std::string *err_msg = NULL);
int chown(RGWBucketAdminOpState& op_state, const string& marker,

View File

@ -1257,7 +1257,7 @@ bool verify_bucket_permission(const DoutPrefixProvider* dpp, struct req_state *
return verify_bucket_permission(dpp,
&ps,
s->bucket->get_bi(),
s->bucket->get_key(),
s->user_acl.get(),
s->bucket_acl.get(),
s->iam_policy,
@ -1271,14 +1271,14 @@ bool verify_bucket_permission(const DoutPrefixProvider* dpp, struct req_state *
int verify_bucket_owner_or_policy(struct req_state* const s,
const uint64_t op)
{
auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, op, ARN(s->bucket->get_bi()));
auto usr_policy_res = eval_user_policies(s->iam_user_policies, s->env, boost::none, op, ARN(s->bucket->get_key()));
if (usr_policy_res == Effect::Deny) {
return -EACCES;
}
auto e = eval_or_pass(s->iam_policy,
s->env, *s->auth.identity,
op, ARN(s->bucket->get_bi()));
op, ARN(s->bucket->get_key()));
if (e == Effect::Deny) {
return -EACCES;
}
@ -1482,7 +1482,7 @@ bool verify_object_permission(const DoutPrefixProvider* dpp, struct req_state *s
return verify_object_permission(dpp,
&ps,
rgw_obj(s->bucket->get_bi(), s->object->get_key()),
rgw_obj(s->bucket->get_key(), s->object->get_key()),
s->user_acl.get(),
s->bucket_acl.get(),
s->object_acl.get(),

View File

@ -4936,7 +4936,7 @@ string RGWBucketPipeSyncStatusManager::obj_status_oid(const rgw_bucket_sync_pipe
const rgw_zone_id& source_zone,
const rgw::sal::RGWObject* obj)
{
string prefix = object_status_oid_prefix + "." + source_zone.id + ":" + obj->get_bucket()->get_key();
string prefix = object_status_oid_prefix + "." + source_zone.id + ":" + obj->get_bucket()->get_key().get_key();
if (sync_pipe.source_bucket_info.bucket !=
sync_pipe.dest_bucket_info.bucket) {
prefix += string("/") + sync_pipe.dest_bucket_info.bucket.get_key();

View File

@ -1609,9 +1609,7 @@ namespace rgw {
return -EIO;
}
op_ret = get_store()->getRados()->check_quota(s->bucket_owner.get_id(),
s->bucket->get_bi(), user_quota, bucket_quota,
real_ofs, true);
op_ret = s->bucket->check_quota(user_quota, bucket_quota, real_ofs, true);
/* max_size exceed */
if (op_ret < 0)
return -EIO;
@ -1653,9 +1651,7 @@ namespace rgw {
goto done;
}
op_ret = get_store()->getRados()->check_quota(s->bucket_owner.get_id(),
s->bucket->get_bi(), user_quota, bucket_quota,
s->obj_size, true);
op_ret = s->bucket->check_quota(user_quota, bucket_quota, s->obj_size, true);
/* max_size exceed */
if (op_ret < 0) {
goto done;

View File

@ -2161,7 +2161,7 @@ public:
uint64_t get_size() { return _size; }
real_time ctime() { return mod_time; } // XXX
real_time mtime() { return mod_time; }
std::map<string, bufferlist>& get_attrs() { return attrs; }
std::map<string, bufferlist>& get_attrs() { return attrs.attrs; }
buffer::list* get_attr(const std::string& k) {
auto iter = attrs.find(k);

View File

@ -28,7 +28,7 @@ void populate_record_from_request(const req_state *s,
// configurationId is filled from notification configuration
record.bucket_name = s->bucket_name;
record.bucket_ownerIdentity = s->bucket_owner.get_id().id;
record.bucket_arn = to_string(rgw::ARN(s->bucket->get_bi()));
record.bucket_arn = to_string(rgw::ARN(s->bucket->get_key()));
record.object_key = obj->get_name();
record.object_size = obj->get_obj_size();
record.object_etag = etag;
@ -69,7 +69,7 @@ int publish(const req_state* s,
EventType event_type,
rgw::sal::RGWRadosStore* store) {
RGWUserPubSub ps_user(store, s->user->get_id());
RGWUserPubSub::Bucket ps_bucket(&ps_user, s->bucket->get_bi());
RGWUserPubSub::Bucket ps_bucket(&ps_user, s->bucket->get_key());
rgw_pubsub_bucket_topics bucket_topics;
auto rc = ps_bucket.get_topics(&bucket_topics);
if (rc < 0) {

File diff suppressed because it is too large Load Diff

View File

@ -75,7 +75,7 @@ class StrategyRegistry;
}
int rgw_op_get_bucket_policy_from_attr(CephContext *cct,
rgw::sal::RGWRadosStore *store,
rgw::sal::RGWStore *store,
RGWBucketInfo& bucket_info,
map<string, bufferlist>& bucket_attrs,
RGWAccessControlPolicy *policy);
@ -274,7 +274,7 @@ protected:
ceph::real_time unmod_time;
ceph::real_time *mod_ptr;
ceph::real_time *unmod_ptr;
map<string, bufferlist> attrs;
rgw::sal::RGWAttrs attrs;
bool get_data;
bool partial_content;
bool ignore_invalid_range;
@ -341,7 +341,7 @@ public:
void execute() override;
int parse_range();
int read_user_manifest_part(
rgw_bucket& bucket,
rgw::sal::RGWBucket* bucket,
const rgw_bucket_dir_entry& ent,
RGWAccessControlPolicy * const bucket_acl,
const boost::optional<rgw::IAM::Policy>& bucket_policy,
@ -1310,7 +1310,7 @@ public:
class RGWPutMetadataBucket : public RGWOp {
protected:
map<string, buffer::list> attrs;
rgw::sal::RGWAttrs attrs;
set<string> rmattr_names;
bool has_policy, has_cors;
uint32_t policy_rw_mask;
@ -2468,7 +2468,4 @@ static inline int parse_value_and_bound(
return 0;
}
int forward_request_to_master(struct req_state *s, obj_version *objv, rgw::sal::RGWRadosStore *store,
bufferlist& in_data, JSONParser *jp, req_info *forward_info = nullptr);
#endif /* CEPH_RGW_OP_H */

View File

@ -473,7 +473,7 @@ int MultipartObjectProcessor::complete(size_t accounted_size,
encode(info, bl);
rgw_obj meta_obj;
meta_obj.init_ns(bucket->get_bi(), mp.get_meta(), RGW_OBJ_NS_MULTIPART);
meta_obj.init_ns(bucket->get_key(), mp.get_meta(), RGW_OBJ_NS_MULTIPART);
meta_obj.set_in_extra_data(true);
rgw_raw_obj raw_meta_obj;

View File

@ -4154,7 +4154,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
bool remote_dest;
append_rand_alpha(cct, dest_obj->get_oid(), shadow_oid, 32);
shadow_obj.init_ns(dest_obj->get_bucket()->get_bi(), shadow_oid, shadow_ns);
shadow_obj.init_ns(dest_obj->get_bucket()->get_key(), shadow_oid, shadow_ns);
auto& zonegroup = svc.zone->get_zonegroup();
@ -4335,7 +4335,7 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
manifest = *astate->manifest;
const rgw_bucket_placement& tail_placement = manifest.get_tail_placement();
if (tail_placement.bucket.name.empty()) {
manifest.set_tail_placement(tail_placement.placement_rule, src_obj->get_bucket()->get_bi());
manifest.set_tail_placement(tail_placement.placement_rule, src_obj->get_bucket()->get_key());
}
string ref_tag;
for (; miter != astate->manifest->obj_end(); ++miter) {

View File

@ -411,6 +411,7 @@ class RGWRados
friend class RGWBucketReshardLock;
friend class BucketIndexLockGuard;
friend class RGWCompleteMultipart;
friend class rgw::sal::RGWRadosStore;
/** Open the pool used as root for this gateway */
int open_root_pool_ctx();
@ -460,7 +461,6 @@ class RGWRados
// This field represents the number of bucket index object shards
uint32_t bucket_index_max_shards;
int get_obj_head_ioctx(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::IoCtx *ioctx);
int get_obj_head_ref(const RGWBucketInfo& bucket_info, const rgw_obj& obj, rgw_rados_ref *ref);
int get_system_obj_ref(const rgw_raw_obj& obj, rgw_rados_ref *ref);
uint64_t max_bucket_id;
@ -506,6 +506,8 @@ protected:
RGWIndexCompletionManager *index_completion_manager{nullptr};
bool use_cache{false};
int get_obj_head_ioctx(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::IoCtx *ioctx);
public:
RGWRados(): timer(NULL),
gc(NULL), lc(NULL), obj_expirer(NULL), use_gc_thread(false), use_lc_thread(false), quota_threads(false),

View File

@ -148,13 +148,11 @@ void RGWOp_Bucket_Link::execute()
op_state.set_bucket_id(bucket_id);
op_state.set_new_bucket_name(new_bucket_name);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWBucketAdminOp::link(store, op_state);
}
@ -188,13 +186,11 @@ void RGWOp_Bucket_Unlink::execute()
op_state.set_user_id(uid);
op_state.set_bucket_name(bucket);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWBucketAdminOp::unlink(store, op_state);
}
@ -215,26 +211,25 @@ public:
void RGWOp_Bucket_Remove::execute()
{
std::string bucket;
std::string bucket_name;
bool delete_children;
std::unique_ptr<rgw::sal::RGWBucket> bucket;
RGWBucketAdminOpState op_state;
RESTArgs::get_string(s, "bucket", bucket, &bucket);
RESTArgs::get_string(s, "bucket", bucket_name, &bucket_name);
RESTArgs::get_bool(s, "purge-objects", false, &delete_children);
op_state.set_bucket_name(bucket);
op_state.set_delete_children(delete_children);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
op_ret = store->get_bucket(nullptr, string(), bucket_name, &bucket);
if (op_ret < 0) {
ldpp_dout(this, 0) << "get_bucket returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWBucketAdminOp::remove_bucket(store, op_state, s->yield);
op_ret = bucket->remove_bucket(delete_children, string(), string(), true, &s->info, s->yield);
if (op_ret < 0) {
ldpp_dout(this, 0) << "remove_bucket returned ret=" << op_ret << dendl;
return;
}
http_ret = op_ret;
}
class RGWOp_Set_Bucket_Quota : public RGWRESTOp {

View File

@ -255,7 +255,7 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs,
/* JSON encode object metadata */
JSONFormatter jf;
jf.open_object_section("obj_metadata");
encode_json("attrs", attrs, &jf);
encode_json("attrs", attrs.attrs, &jf);
utime_t ut(lastmod);
encode_json("mtime", ut, &jf);
jf.close_section();
@ -270,14 +270,14 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs,
/* we end up dumping mtime in two different methods, a bit redundant */
dump_epoch_header(s, "Rgwx-Mtime", lastmod);
uint64_t pg_ver = 0;
int r = decode_attr_bl_single_value(attrs, RGW_ATTR_PG_VER, &pg_ver, (uint64_t)0);
int r = decode_attr_bl_single_value(attrs.attrs, RGW_ATTR_PG_VER, &pg_ver, (uint64_t)0);
if (r < 0) {
ldpp_dout(this, 0) << "ERROR: failed to decode pg ver attr, ignoring" << dendl;
}
dump_header(s, "Rgwx-Obj-PG-Ver", pg_ver);
uint32_t source_zone_short_id = 0;
r = decode_attr_bl_single_value(attrs, RGW_ATTR_SOURCE_ZONE, &source_zone_short_id, (uint32_t)0);
r = decode_attr_bl_single_value(attrs.attrs, RGW_ATTR_SOURCE_ZONE, &source_zone_short_id, (uint32_t)0);
if (r < 0) {
ldpp_dout(this, 0) << "ERROR: failed to decode pg ver attr, ignoring" << dendl;
}
@ -443,7 +443,7 @@ int RGWGetObj_ObjStore_S3::get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>
int res = 0;
std::unique_ptr<BlockCrypt> block_crypt;
res = rgw_s3_prepare_decrypt(s, attrs, &block_crypt, crypt_http_responses);
res = rgw_s3_prepare_decrypt(s, attrs.attrs, &block_crypt, crypt_http_responses);
if (res == 0) {
if (block_crypt != nullptr) {
auto f = std::make_unique<RGWGetObj_BlockDecrypt>(s->cct, cb, std::move(block_crypt));
@ -2663,7 +2663,7 @@ int RGWPutObj_ObjStore_S3::get_encrypt_filter(
if (!multipart_upload_id.empty()) {
RGWMPObj mp(s->object->get_name(), multipart_upload_id);
rgw_obj obj;
obj.init_ns(s->bucket->get_bi(), mp.get_meta(), RGW_OBJ_NS_MULTIPART);
obj.init_ns(s->bucket->get_key(), mp.get_meta(), RGW_OBJ_NS_MULTIPART);
obj.set_in_extra_data(true);
map<string, bufferlist> xattrs;
res = get_obj_attrs(store, s, obj, xattrs);
@ -4949,7 +4949,7 @@ bool RGWHandler_REST_S3Website::web_dir() const {
subdir_name.pop_back();
}
rgw_obj obj(s->bucket->get_bi(), subdir_name);
rgw_obj obj(s->bucket->get_key(), subdir_name);
RGWObjectCtx& obj_ctx = *static_cast<RGWObjectCtx *>(s->obj_ctx);
obj_ctx.set_atomic(obj);
@ -5134,9 +5134,13 @@ int RGWHandler_REST_S3Website::error_handler(int err_no,
ldpp_dout(s, 10) << "RGWHandler_REST_S3Website::error_handler err_no=" << err_no << " http_ret=" << http_error_code << dendl;
RGWBWRoutingRule rrule;
bool should_redirect =
s->bucket->get_info().website_conf.should_redirect(original_object_name,
http_error_code, &rrule);
bool have_bucket = !rgw::sal::RGWBucket::empty(s->bucket.get());
bool should_redirect = false;
if (have_bucket) {
should_redirect =
s->bucket->get_info().website_conf.should_redirect(original_object_name,
http_error_code, &rrule);
}
if (should_redirect) {
const string& hostname = s->info.env->get("HTTP_HOST", "");
@ -5155,7 +5159,7 @@ int RGWHandler_REST_S3Website::error_handler(int err_no,
} else if (err_no == -ERR_WEBSITE_REDIRECT) {
// Do nothing here, this redirect will be handled in abort_early's ERR_WEBSITE_REDIRECT block
// Do NOT fire the ErrorDoc handler
} else if (!s->bucket->get_info().website_conf.error_doc.empty()) {
} else if (have_bucket && !s->bucket->get_info().website_conf.error_doc.empty()) {
/* This serves an entire page!
On success, it will return zero, and no further content should be sent to the socket
On failure, we need the double-error handler

View File

@ -858,7 +858,7 @@ int RGWPutObj_ObjStore_SWIFT::update_slo_segment_size(rgw_slo_entry& entry) {
}
bucket = bucket_info.bucket;
} else {
bucket = s->bucket->get_bi();
bucket = s->bucket->get_key();
}
/* fetch the stored size of the seg (or error if not valid) */
@ -1553,8 +1553,8 @@ int RGWGetObj_ObjStore_SWIFT::send_response_data(bufferlist& bl,
}
}
get_contype_from_attrs(attrs, content_type);
dump_object_metadata(this, s, attrs);
get_contype_from_attrs(attrs.attrs, content_type);
dump_object_metadata(this, s, attrs.attrs);
}
end_header(s, this, !content_type.empty() ? content_type.c_str()

View File

@ -223,13 +223,11 @@ void RGWOp_User_Create::execute()
op_state.set_placement_tags(placement_tags_list);
}
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_User::create(store, op_state, flusher);
}
@ -367,13 +365,11 @@ void RGWOp_User_Modify::execute()
op_state.set_placement_tags(placement_tags_list);
}
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_User::modify(store, op_state, flusher);
}
@ -410,13 +406,11 @@ void RGWOp_User_Remove::execute()
op_state.set_purge_data(purge_data);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_User::remove(store, op_state, flusher, s->yield);
}
@ -488,13 +482,11 @@ void RGWOp_Subuser_Create::execute()
}
op_state.set_key_type(key_type);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_Subuser::create(store, op_state, flusher);
}
@ -557,13 +549,11 @@ void RGWOp_Subuser_Modify::execute()
}
op_state.set_key_type(key_type);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_Subuser::modify(store, op_state, flusher);
}
@ -602,13 +592,11 @@ void RGWOp_Subuser_Remove::execute()
if (purge_keys)
op_state.set_purge_keys();
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_Subuser::remove(store, op_state, flusher);
}
@ -745,13 +733,11 @@ void RGWOp_Caps_Add::execute()
op_state.set_user_id(uid);
op_state.set_caps(caps);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_Caps::add(store, op_state, flusher);
}
@ -785,13 +771,11 @@ void RGWOp_Caps_Remove::execute()
op_state.set_user_id(uid);
op_state.set_caps(caps);
if (!store->svc()->zone->is_meta_master()) {
bufferlist data;
op_ret = forward_request_to_master(s, nullptr, store, data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
bufferlist data;
op_ret = store->forward_request_to_master(s->user, nullptr, data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
http_ret = RGWUserAdminOp_Caps::remove(store, op_state, flusher);
}

View File

@ -132,13 +132,11 @@ void RGWPutUserPolicy::execute()
return;
}
if (!store->svc()->zone->is_meta_master()) {
ceph::bufferlist in_data;
op_ret = forward_request_to_master(s, nullptr, store, in_data, nullptr);
if (op_ret < 0) {
ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
ceph::bufferlist in_data;
op_ret = store->forward_request_to_master(s->user, nullptr, in_data, nullptr, s->info);
if (op_ret < 0) {
ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
try {
@ -338,18 +336,16 @@ void RGWDeleteUserPolicy::execute()
return;
}
if (!store->svc()->zone->is_meta_master()) {
ceph::bufferlist in_data;
op_ret = forward_request_to_master(s, nullptr, store, in_data, nullptr);
if (op_ret < 0) {
// a policy might've been uploaded to this site when there was no sync
// req. in earlier releases, proceed deletion
if (op_ret != -ENOENT) {
ldpp_dout(this, 5) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret << dendl;
ceph::bufferlist in_data;
op_ret = store->forward_request_to_master(s->user, nullptr, in_data, nullptr, s->info);
if (op_ret < 0) {
// a policy might've been uploaded to this site when there was no sync
// req. in earlier releases, proceed deletion
if (op_ret != -ENOENT) {
ldpp_dout(this, 5) << "forward_request_to_master returned ret=" << op_ret << dendl;
return;
}
ldpp_dout(this, 0) << "ERROR: forward_request_to_master returned ret=" << op_ret << dendl;
}
map<string, string> policies;

View File

@ -81,44 +81,36 @@ RGWObject *RGWRadosBucket::create_object(const rgw_obj_key &key)
return nullptr;
}
int RGWRadosBucket::remove_bucket(bool delete_children, std::string prefix, std::string delimiter, optional_yield y)
int RGWRadosBucket::remove_bucket(bool delete_children, std::string prefix, std::string delimiter, bool forward_to_master, req_info* req_info, optional_yield y)
{
int ret;
map<RGWObjCategory, RGWStorageStats> stats;
std::vector<rgw_bucket_dir_entry> objs;
map<string, bool> common_prefixes;
string bucket_ver, master_ver;
// Refresh info
ret = get_bucket_info(y);
if (ret < 0)
return ret;
ret = get_bucket_stats(info, RGW_NO_SHARD, &bucket_ver, &master_ver, stats);
if (ret < 0)
return ret;
ListParams params;
params.list_versions = true;
params.allow_unordered = true;
RGWRados::Bucket target(store->getRados(), info);
RGWRados::Bucket::List list_op(&target);
int max = 1000;
list_op.params.list_versions = true;
list_op.params.allow_unordered = true;
ListResults results;
bool is_truncated = false;
do {
objs.clear();
results.objs.clear();
ret = list_op.list_objects(max, &objs, &common_prefixes, &is_truncated, null_yield);
if (ret < 0)
return ret;
ret = list(params, 1000, results, y);
if (ret < 0)
return ret;
if (!objs.empty() && !delete_children) {
if (!results.objs.empty() && !delete_children) {
lderr(store->ctx()) << "ERROR: could not remove non-empty bucket " << info.bucket.name <<
dendl;
return -ENOTEMPTY;
}
for (const auto& obj : objs) {
for (const auto& obj : results.objs) {
rgw_obj_key key(obj.key);
/* xxx dang */
ret = rgw_remove_object(store, info, info.bucket, key);
@ -128,9 +120,12 @@ int RGWRadosBucket::remove_bucket(bool delete_children, std::string prefix, std:
}
} while(is_truncated);
ret = abort_bucket_multiparts(store, store->ctx(), info, prefix, delimiter);
if (ret < 0) {
return ret;
/* If there's a prefix, then we are aborting multiparts as well */
if (!prefix.empty()) {
ret = abort_bucket_multiparts(store, store->ctx(), info, prefix, delimiter);
if (ret < 0) {
return ret;
}
}
ret = store->ctl()->bucket->sync_user_stats(info.owner, info);
@ -138,11 +133,11 @@ int RGWRadosBucket::remove_bucket(bool delete_children, std::string prefix, std:
ldout(store->ctx(), 1) << "WARNING: failed sync user stats before bucket delete. ret=" << ret << dendl;
}
RGWObjVersionTracker objv_tracker;
RGWObjVersionTracker ot;
// if we deleted children above we will force delete, as any that
// remain is detrius from a prior bug
ret = store->getRados()->delete_bucket(info, objv_tracker, null_yield, !delete_children);
ret = store->getRados()->delete_bucket(info, ot, null_yield, !delete_children);
if (ret < 0) {
lderr(store->ctx()) << "ERROR: could not remove bucket " <<
info.bucket.name << dendl;
@ -154,6 +149,19 @@ int RGWRadosBucket::remove_bucket(bool delete_children, std::string prefix, std:
lderr(store->ctx()) << "ERROR: unable to remove user bucket information" << dendl;
}
if (forward_to_master) {
bufferlist in_data;
ret = store->forward_request_to_master(owner, &ot.read_version, in_data, nullptr, *req_info);
if (ret < 0) {
if (ret == -ENOENT) {
/* adjust error, we want to return with NoSuchBucket and not
* NoSuchKey */
ret = -ERR_NO_SUCH_BUCKET;
}
return ret;
}
}
return ret;
}
@ -284,10 +292,21 @@ int RGWRadosBucket::check_empty(optional_yield y)
return store->getRados()->check_bucket_empty(info, y);
}
int RGWRadosBucket::check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size)
int RGWRadosBucket::check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size, bool check_size_only)
{
return store->getRados()->check_quota(owner->get_user(), get_bi(),
user_quota, bucket_quota, obj_size);
return store->getRados()->check_quota(owner->get_user(), get_key(),
user_quota, bucket_quota, obj_size, check_size_only);
}
int RGWRadosBucket::set_instance_attrs(RGWAttrs& attrs, optional_yield y)
{
return store->ctl()->bucket->set_bucket_instance_attrs(get_info(),
attrs.attrs, &get_info().objv_tracker, y);
}
int RGWRadosBucket::try_refresh_info(ceph::real_time *pmtime)
{
return store->getRados()->try_refresh_bucket_info(info, pmtime, &attrs.attrs);
}
int RGWRadosBucket::set_acl(RGWAccessControlPolicy &acl, optional_yield y)
@ -305,6 +324,29 @@ std::unique_ptr<RGWObject> RGWRadosBucket::get_object(const rgw_obj_key& k)
return std::unique_ptr<RGWObject>(new RGWRadosObject(this->store, k, this));
}
int RGWRadosBucket::list(ListParams& params, int max, ListResults& results, optional_yield y)
{
RGWRados::Bucket target(store->getRados(), get_info());
if (params.shard_id >= 0) {
target.set_shard_id(params.shard_id);
}
RGWRados::Bucket::List list_op(&target);
list_op.params.prefix = params.prefix;
list_op.params.delim = params.delim;
list_op.params.marker = params.marker;
list_op.params.end_marker = params.end_marker;
list_op.params.list_versions = params.list_versions;
list_op.params.allow_unordered = params.allow_unordered;
int ret = list_op.list_objects(max, &results.objs, &results.common_prefixes, &results.is_truncated, y);
if (ret >= 0) {
results.next_marker = list_op.get_next_marker();
}
return ret;
}
std::unique_ptr<RGWUser> RGWRadosStore::get_user(const rgw_user &u)
{
return std::unique_ptr<RGWUser>(new RGWRadosUser(this, u));
@ -325,9 +367,31 @@ void RGWRadosStore::finalize(void)
rados->finalize();
}
int RGWObject::range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end)
{
if (ofs < 0) {
ofs += obj_size;
if (ofs < 0)
ofs = 0;
end = obj_size - 1;
} else if (end < 0) {
end = obj_size - 1;
}
if (obj_size > 0) {
if (ofs >= (off_t)obj_size) {
return -ERANGE;
}
if (end >= (off_t)obj_size) {
end = obj_size - 1;
}
}
return 0;
}
int RGWRadosObject::get_obj_state(RGWObjectCtx *rctx, RGWBucket& bucket, RGWObjState **state, optional_yield y, bool follow_olh)
{
rgw_obj obj(bucket.get_bi(), key.name);
rgw_obj obj(bucket.get_key(), key.name);
return store->getRados()->get_obj_state(rctx, bucket.get_info(), obj, state, follow_olh, y);
}
@ -342,7 +406,23 @@ int RGWRadosObject::read_attrs(RGWRados::Object::Read &read_op, optional_yield y
return read_op.prepare(y);
}
int RGWRadosObject::get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj *target_obj)
int RGWRadosObject::set_obj_attrs(RGWObjectCtx* rctx, RGWAttrs* setattrs, RGWAttrs* delattrs, optional_yield y, rgw_obj* target_obj)
{
map<string, bufferlist> empty;
rgw_obj target = get_obj();
if (!target_obj)
target_obj = &target;
return store->getRados()->set_attrs(rctx,
bucket->get_info(),
*target_obj,
setattrs ? setattrs->attrs : empty,
delattrs ? &delattrs->attrs : nullptr,
y);
}
int RGWRadosObject::get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj* target_obj)
{
RGWRados::Object op_target(store->getRados(), bucket->get_info(), *rctx, get_obj());
RGWRados::Object::Read read_op(&op_target);
@ -352,14 +432,24 @@ int RGWRadosObject::get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj
int RGWRadosObject::modify_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, bufferlist& attr_val, optional_yield y)
{
rgw_obj target_obj;
int r = get_obj_attrs(rctx, y, &target_obj);
rgw_obj target = get_obj();
int r = get_obj_attrs(rctx, y, &target);
if (r < 0) {
return r;
}
set_atomic(rctx);
attrs.attrs[attr_name] = attr_val;
return store->getRados()->set_attrs(rctx, bucket->get_info(), target_obj, attrs.attrs, NULL, y);
return set_obj_attrs(rctx, &attrs, nullptr, y, &target);
}
int RGWRadosObject::delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y)
{
RGWAttrs rmattr;
bufferlist bl;
set_atomic(rctx);
rmattr.attrs[attr_name] = bl;
return set_obj_attrs(rctx, nullptr, &rmattr, y);
}
int RGWRadosObject::copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket,
@ -383,21 +473,9 @@ int RGWRadosObject::copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket,
attrset.erase(RGW_ATTR_TAIL_TAG);
return store->getRados()->copy_obj_data(rctx, dest_bucket,
dest_bucket->get_info().placement_rule, read_op,
obj_size - 1, dest_obj, NULL, mtime, attrset, 0, real_time(), NULL,
dpp, y);
}
int RGWRadosObject::delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y)
{
map <string, bufferlist> attrs;
map <string, bufferlist> rmattr;
bufferlist bl;
set_atomic(rctx);
rmattr[attr_name] = bl;
rgw_obj obj = get_obj();
return store->getRados()->set_attrs(rctx, bucket->get_info(), obj, attrs, &rmattr, y);
dest_bucket->get_info().placement_rule, read_op,
obj_size - 1, dest_obj, NULL, mtime, attrset, 0,
real_time(), NULL, dpp, y);
}
void RGWRadosObject::set_atomic(RGWObjectCtx *rctx) const
@ -412,11 +490,131 @@ void RGWRadosObject::set_prefetch_data(RGWObjectCtx *rctx)
store->getRados()->set_prefetch_data(rctx, obj);
}
bool RGWRadosObject::is_expired() {
map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_DELETE_AT);
if (iter != attrs.end()) {
utime_t delete_at;
try {
auto bufit = iter->second.cbegin();
decode(delete_at, bufit);
} catch (buffer::error& err) {
ldout(store->ctx(), 0) << "ERROR: " << __func__ << ": failed to decode " RGW_ATTR_DELETE_AT " attr" << dendl;
return false;
}
if (delete_at <= ceph_clock_now() && !delete_at.is_zero()) {
return true;
}
}
return false;
}
void RGWRadosObject::gen_rand_obj_instance_name()
{
store->getRados()->gen_rand_obj_instance_name(&key);
}
int RGWRadosObject::omap_get_vals_by_keys(const std::string& oid,
const std::set<std::string>& keys,
std::map<std::string, bufferlist> *vals)
{
int ret;
rgw_raw_obj head_obj;
librados::IoCtx cur_ioctx;
rgw_obj obj = get_obj();
store->getRados()->obj_to_raw(bucket->get_placement_rule(), obj, &head_obj);
ret = store->get_obj_head_ioctx(bucket->get_info(), obj, &cur_ioctx);
if (ret < 0) {
return ret;
}
return cur_ioctx.omap_get_vals_by_keys(oid, keys, vals);
}
std::unique_ptr<RGWObject::ReadOp> RGWRadosObject::get_read_op(RGWObjectCtx *ctx)
{
return std::unique_ptr<RGWObject::ReadOp>(new RGWRadosObject::RadosReadOp(this, ctx));
}
RGWRadosObject::RadosReadOp::RadosReadOp(RGWRadosObject *_source, RGWObjectCtx *_rctx) :
source(_source),
rctx(_rctx),
op_target(_source->store->getRados(),
_source->get_bucket()->get_info(),
*static_cast<RGWObjectCtx *>(rctx),
_source->get_obj()),
parent_op(&op_target)
{ }
int RGWRadosObject::RadosReadOp::prepare(optional_yield y)
{
uint64_t obj_size;
parent_op.conds.mod_ptr = params.mod_ptr;
parent_op.conds.unmod_ptr = params.unmod_ptr;
parent_op.conds.high_precision_time = params.high_precision_time;
parent_op.conds.mod_zone_id = params.mod_zone_id;
parent_op.conds.mod_pg_ver = params.mod_pg_ver;
parent_op.conds.if_match = params.if_match;
parent_op.conds.if_nomatch = params.if_nomatch;
parent_op.params.lastmod = params.lastmod;
parent_op.params.target_obj = params.target_obj;
parent_op.params.obj_size = &obj_size;
parent_op.params.attrs = &source->get_attrs().attrs;
int ret = parent_op.prepare(y);
if (ret < 0)
return ret;
source->set_key(parent_op.state.obj.key);
source->set_obj_size(obj_size);
result.head_obj = parent_op.state.head_obj;
return ret;
}
int RGWRadosObject::RadosReadOp::read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y)
{
return parent_op.read(ofs, end, bl, y);
}
int RGWRadosObject::RadosReadOp::get_manifest(RGWObjManifest **pmanifest,
optional_yield y)
{
return op_target.get_manifest(pmanifest, y);
}
int RGWRadosObject::delete_object(RGWObjectCtx* obj_ctx, ACLOwner obj_owner, ACLOwner bucket_owner, ceph::real_time unmod_since, bool high_precision_time, uint64_t epoch, string& version_id, optional_yield y)
{
int ret = 0;
RGWRados::Object del_target(store->getRados(), bucket->get_info(), *obj_ctx, get_obj());
RGWRados::Object::Delete del_op(&del_target);
del_op.params.olh_epoch = epoch;
del_op.params.marker_version_id = version_id;
del_op.params.bucket_owner = bucket_owner.get_id();
del_op.params.versioning_status = bucket->get_info().versioning_status();
del_op.params.obj_owner = obj_owner;
del_op.params.unmod_since = unmod_since;
del_op.params.high_precision_time = high_precision_time;
ret = del_op.delete_obj(y);
if (ret >= 0) {
delete_marker = del_op.result.delete_marker;
version_id = del_op.result.version_id;
}
return ret;
}
int RGWRadosObject::RadosReadOp::iterate(int64_t ofs, int64_t end, RGWGetDataCB *cb, optional_yield y)
{
return parent_op.iterate(ofs, end, cb, y);
}
int RGWRadosStore::get_bucket(RGWUser* u, const rgw_bucket& b, std::unique_ptr<RGWBucket>* bucket)
{
int ret;
@ -497,10 +695,20 @@ static int rgw_op_get_bucket_policy_from_attr(RGWRadosStore *store,
return 0;
}
bool RGWRadosStore::is_meta_master()
{
return svc()->zone->is_meta_master();
}
int RGWRadosStore::forward_request_to_master(RGWUser* user, obj_version *objv,
bufferlist& in_data,
JSONParser *jp, req_info& info)
{
if (is_meta_master()) {
/* We're master, don't forward */
return 0;
}
if (!svc()->zone->get_master_conn()) {
ldout(ctx(), 0) << "rest connection is invalid" << dendl;
return -EINVAL;
@ -527,8 +735,8 @@ int RGWRadosStore::forward_request_to_master(RGWUser* user, obj_version *objv,
int RGWRadosStore::create_bucket(RGWUser& u, const rgw_bucket& b,
const string& zonegroup_id,
const rgw_placement_rule& placement_rule,
const string& swift_ver_location,
rgw_placement_rule& placement_rule,
string& swift_ver_location,
const RGWQuotaInfo * pquota_info,
map<std::string, bufferlist>& attrs,
RGWBucketInfo& info,
@ -556,6 +764,10 @@ int RGWRadosStore::create_bucket(RGWUser& u, const rgw_bucket& b,
if (ret != -ENOENT) {
*existed = true;
if (swift_ver_location.empty()) {
swift_ver_location = bucket->get_info().swift_ver_location;
}
placement_rule.inherit_from(bucket->get_info().placement_rule);
int r = rgw_op_get_bucket_policy_from_attr(this, u, bucket->get_attrs().attrs,
&old_policy);
if (r >= 0) {
@ -615,7 +827,7 @@ int RGWRadosStore::create_bucket(RGWUser& u, const rgw_bucket& b,
}
} else {
ret = getRados()->create_bucket(u.get_info(), bucket->get_bi(),
ret = getRados()->create_bucket(u.get_info(), bucket->get_key(),
zid, placement_rule, swift_ver_location,
pquota_info, attrs,
info, pobjv, &ep_objv, creation_time,
@ -684,6 +896,11 @@ rgw::sal::RGWRadosStore *RGWStoreManager::init_raw_storage_provider(CephContext
return store;
}
int rgw::sal::RGWRadosStore::get_obj_head_ioctx(const RGWBucketInfo& bucket_info, const rgw_obj& obj, librados::IoCtx *ioctx)
{
return rados->get_obj_head_ioctx(bucket_info, obj, ioctx);
}
void RGWStoreManager::close_storage(rgw::sal::RGWRadosStore *store)
{
if (!store)

View File

@ -36,10 +36,26 @@ struct RGWAttrs {
void emplace(std::string&& key, buffer::list&& bl) {
attrs.emplace(std::move(key), std::move(bl)); /* key and bl are r-value refs */
map<string, bufferlist>::iterator find(const std::string& key);
}
std::size_t erase(const std::string& key) {
return attrs.erase(key);
}
std::map<std::string, bufferlist>::iterator find(const std::string& key) {
return attrs.find(key);
}
std::map<std::string, bufferlist>::iterator end() {
return attrs.end();
}
std::map<std::string, bufferlist>::iterator begin() {
return attrs.begin();
}
ceph::buffer::list& operator[](const std::string& k) {
return attrs[k];
}
ceph::buffer::list& operator[](std::string&& k) {
return attrs[k];
}
};
class RGWStore : public DoutPrefixProvider {
@ -53,9 +69,9 @@ class RGWStore : public DoutPrefixProvider {
virtual int get_bucket(RGWUser* u, const RGWBucketInfo& i, std::unique_ptr<RGWBucket>* bucket) = 0;
virtual int get_bucket(RGWUser* u, const std::string& tenant, const std::string&name, std::unique_ptr<RGWBucket>* bucket) = 0;
virtual int create_bucket(RGWUser& u, const rgw_bucket& b,
const string& zonegroup_id,
const rgw_placement_rule& placement_rule,
const string& swift_ver_location,
const std::string& zonegroup_id,
rgw_placement_rule& placement_rule,
std::string& swift_ver_location,
const RGWQuotaInfo * pquota_info,
map<std::string, bufferlist>& attrs,
RGWBucketInfo& info,
@ -66,6 +82,9 @@ class RGWStore : public DoutPrefixProvider {
req_info& req_info,
std::unique_ptr<RGWBucket>* bucket) = 0;
virtual RGWBucketList* list_buckets(void) = 0;
virtual bool is_meta_master() = 0;
virtual int forward_request_to_master(RGWUser* user, obj_version *objv,
bufferlist& in_data, JSONParser *jp, req_info& info) = 0;
virtual void finalize(void)=0;
@ -82,7 +101,7 @@ class RGWUser {
RGWUser(const RGWUserInfo& _i) : info(_i) {}
virtual ~RGWUser() = default;
virtual int list_buckets(const string& marker, const string& end_marker,
virtual int list_buckets(const std::string& marker, const std::string& end_marker,
uint64_t max, bool need_stats, RGWBucketList& buckets) = 0;
virtual RGWBucket* create_bucket(rgw_bucket& bucket, ceph::real_time creation_time) = 0;
friend class RGWBucket;
@ -112,6 +131,26 @@ class RGWBucket {
ceph::real_time mtime;
public:
struct ListParams {
std::string prefix;
std::string delim;
rgw_obj_key marker;
rgw_obj_key end_marker;
std::string ns;
bool enforce_ns{true};
RGWAccessListFilter *filter{nullptr};
bool list_versions{false};
bool allow_unordered{false};
int shard_id{0};
};
struct ListResults {
vector<rgw_bucket_dir_entry> objs;
map<std::string, bool> common_prefixes;
bool is_truncated;
rgw_obj_key next_marker;
};
RGWBucket() : ent(), info(), owner(nullptr), attrs(), bucket_version() {}
RGWBucket(const rgw_bucket& _b) :
ent(), info(), owner(nullptr), attrs(), bucket_version() { ent.bucket = _b; info.bucket = _b; }
@ -129,11 +168,11 @@ class RGWBucket {
virtual int load_by_name(const std::string& tenant, const std::string& bucket_name, const std::string bucket_instance_id, RGWSysObjectCtx *rctx, optional_yield y) = 0;
virtual std::unique_ptr<RGWObject> get_object(const rgw_obj_key& key) = 0;
virtual RGWBucketList* list(void) = 0;
virtual int list(ListParams&, int, ListResults&, optional_yield y) = 0;
virtual RGWObject* create_object(const rgw_obj_key& key /* Attributes */) = 0;
virtual RGWAttrs& get_attrs(void) { return attrs; }
virtual int set_attrs(RGWAttrs a) { attrs = a; return 0; }
virtual int remove_bucket(bool delete_children, std::string prefix, std::string delimiter, optional_yield y) = 0;
virtual int remove_bucket(bool delete_children, std::string prefix, std::string delimiter, bool forward_to_master, req_info* req_info, optional_yield y) = 0;
virtual RGWAccessControlPolicy& get_acl(void) = 0;
virtual int set_acl(RGWAccessControlPolicy& acl, optional_yield y) = 0;
virtual int get_bucket_info(optional_yield y) = 0;
@ -152,7 +191,9 @@ class RGWBucket {
virtual int put_instance_info(bool exclusive, ceph::real_time mtime) = 0;
virtual bool is_owner(RGWUser* user) = 0;
virtual int check_empty(optional_yield y) = 0;
virtual int check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size) = 0;
virtual int check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size, bool check_size_only = false) = 0;
virtual int set_instance_attrs(RGWAttrs& attrs, optional_yield y) = 0;
virtual int try_refresh_info(ceph::real_time *pmtime) = 0;
bool empty() const { return info.bucket.name.empty(); }
const std::string& get_name() const { return info.bucket.name; }
@ -167,7 +208,6 @@ class RGWBucket {
ceph::real_time& get_modification_time() { return mtime; }
obj_version& get_version() { return bucket_version; }
void set_version(obj_version &ver) { bucket_version = ver; }
std::string get_key() { return info.bucket.get_key(); }
bool versioned() { return info.versioned(); }
bool versioning_enabled() { return info.versioning_enabled(); }
@ -179,7 +219,7 @@ class RGWBucket {
virtual std::unique_ptr<RGWBucket> clone() = 0;
/* dang - This is temporary, until the API is completed */
rgw_bucket& get_bi() { return info.bucket; }
rgw_bucket& get_key() { return info.bucket; }
RGWBucketInfo& get_info() { return info; }
friend inline ostream& operator<<(ostream& out, const RGWBucket& b) {
@ -226,7 +266,7 @@ public:
return *this;
};
map<string, std::unique_ptr<RGWBucket>>& get_buckets() { return buckets; }
map<std::string, std::unique_ptr<RGWBucket>>& get_buckets() { return buckets; }
bool is_truncated(void) const { return truncated; }
void set_truncated(bool trunc) { truncated = trunc; }
void add(std::unique_ptr<RGWBucket> bucket) {
@ -245,21 +285,73 @@ class RGWObject {
RGWBucket* bucket;
std::string index_hash_source;
uint64_t obj_size;
RGWAttrs attrs;
ceph::real_time mtime;
bool delete_marker;
public:
RGWObject() : key(), bucket(nullptr), index_hash_source(), obj_size(), mtime() {}
RGWObject(const rgw_obj_key& _k) : key(_k), bucket(), index_hash_source(), obj_size(), mtime() {}
RGWObject(const rgw_obj_key& _k, RGWBucket* _b) : key(_k), bucket(_b), index_hash_source(), obj_size(), mtime() {}
RGWObject(const RGWObject& _o) = default;
struct ReadOp {
struct Params {
const ceph::real_time *mod_ptr{nullptr};
const ceph::real_time *unmod_ptr{nullptr};
bool high_precision_time{false};
uint32_t mod_zone_id{0};
uint64_t mod_pg_ver{0};
const char *if_match{nullptr};
const char *if_nomatch{nullptr};
ceph::real_time *lastmod{nullptr};
rgw_obj *target_obj{nullptr}; // XXX dang remove?
} params;
struct Result {
rgw_raw_obj head_obj;
Result() : head_obj() {}
} result;
virtual ~ReadOp() = default;
virtual int prepare(optional_yield y) = 0;
virtual int read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y) = 0;
virtual int iterate(int64_t ofs, int64_t end, RGWGetDataCB *cb, optional_yield y) = 0;
virtual int get_manifest(RGWObjManifest **pmanifest, optional_yield y) = 0;
};
RGWObject()
: key(),
bucket(nullptr),
index_hash_source(),
obj_size(),
attrs(),
mtime(),
delete_marker(false) {}
RGWObject(const rgw_obj_key& _k)
: key(_k),
bucket(),
index_hash_source(),
obj_size(),
attrs(),
mtime(),
delete_marker(false) {}
RGWObject(const rgw_obj_key& _k, RGWBucket* _b)
: key(_k),
bucket(_b),
index_hash_source(),
obj_size(),
attrs(),
mtime(),
delete_marker(false) {}
RGWObject(RGWObject& _o) = default;
virtual ~RGWObject() = default;
virtual int read(off_t offset, off_t length, std::iostream& stream) = 0;
virtual int write(off_t offset, off_t length, std::iostream& stream) = 0;
virtual RGWAttrs& get_attrs(void) = 0;
virtual int set_attrs(RGWAttrs& attrs) = 0;
virtual int delete_object(void) = 0;
virtual int delete_object(RGWObjectCtx* obj_ctx, ACLOwner obj_owner,
ACLOwner bucket_owner, ceph::real_time unmod_since,
bool high_precision_time, uint64_t epoch,
std::string& version_id,optional_yield y) = 0;
virtual RGWAccessControlPolicy& get_acl(void) = 0;
virtual int set_acl(const RGWAccessControlPolicy& acl) = 0;
virtual void set_atomic(RGWObjectCtx *rctx) const = 0;
@ -269,11 +361,14 @@ class RGWObject {
const std::string &get_name() const { return key.name; }
virtual int get_obj_state(RGWObjectCtx *rctx, RGWBucket& bucket, RGWObjState **state, optional_yield y, bool follow_olh = false) = 0;
virtual int get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj *target_obj = nullptr) = 0;
virtual int set_obj_attrs(RGWObjectCtx* rctx, RGWAttrs* setattrs, RGWAttrs* delattrs, optional_yield y, rgw_obj* target_obj = NULL) = 0;
virtual int get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj* target_obj = NULL) = 0;
virtual int modify_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, bufferlist& attr_val, optional_yield y) = 0;
virtual int delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y) = 0;
virtual int copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket, RGWObject* dest_obj, uint16_t olh_epoch, std::string* petag, const DoutPrefixProvider *dpp, optional_yield y) = 0;
virtual bool is_expired() = 0;
RGWAttrs& get_attrs(void) { return attrs; }
ceph::real_time get_mtime(void) const { return mtime; }
uint64_t get_obj_size(void) const { return obj_size; }
RGWBucket* get_bucket(void) const { return bucket; }
@ -281,15 +376,25 @@ class RGWObject {
std::string get_hash_source(void) { return index_hash_source; }
void set_hash_source(std::string s) { index_hash_source = s; }
std::string get_oid(void) const { return key.get_oid(); }
bool get_delete_marker(void) { return delete_marker; }
int range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end);
/* OPs */
virtual std::unique_ptr<ReadOp> get_read_op(RGWObjectCtx *) = 0;
/* OMAP */
virtual int omap_get_vals_by_keys(const std::string& oid,
const std::set<std::string>& keys,
std::map<std::string, bufferlist> *vals) = 0;
static bool empty(RGWObject* o) { return (!o || o->empty()); }
virtual std::unique_ptr<RGWObject> clone() = 0;
/* dang - Not sure if we want this, but it simplifies things a lot */
void set_obj_size(uint64_t s) { obj_size = s; }
virtual void set_name(const string& n) { key = n; }
virtual void set_name(const std::string& n) { key = n; }
virtual void set_key(const rgw_obj_key& k) { key = k; }
virtual rgw_obj get_obj(void) const { return rgw_obj(bucket->get_bi(), key); }
virtual rgw_obj get_obj(void) const { return rgw_obj(bucket->get_key(), key); }
virtual void gen_rand_obj_instance_name() = 0;
/* dang - This is temporary, until the API is completed */
@ -328,7 +433,7 @@ class RGWRadosUser : public RGWUser {
RGWRadosUser(RGWRadosStore *_st) : store(_st) { }
RGWRadosUser() {}
int list_buckets(const string& marker, const string& end_marker,
int list_buckets(const std::string& marker, const std::string& end_marker,
uint64_t max, bool need_stats, RGWBucketList& buckets);
RGWBucket* create_bucket(rgw_bucket& bucket, ceph::real_time creation_time);
@ -341,50 +446,71 @@ class RGWRadosUser : public RGWUser {
class RGWRadosObject : public RGWObject {
private:
RGWRadosStore *store;
RGWAttrs attrs;
RGWAccessControlPolicy acls;
public:
RGWRadosObject()
: store(),
attrs(),
acls() {
}
struct RadosReadOp : public ReadOp {
private:
RGWRadosObject* source;
RGWObjectCtx* rctx;
RGWRados::Object op_target;
RGWRados::Object::Read parent_op;
public:
RadosReadOp(RGWRadosObject *_source, RGWObjectCtx *_rctx);
virtual int prepare(optional_yield y) override;
virtual int read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y) override;
virtual int iterate(int64_t ofs, int64_t end, RGWGetDataCB *cb, optional_yield y) override;
virtual int get_manifest(RGWObjManifest **pmanifest, optional_yield y) override;
};
RGWRadosObject() = default;
RGWRadosObject(RGWRadosStore *_st, const rgw_obj_key& _k)
: RGWObject(_k),
store(_st),
attrs(),
acls() {
}
RGWRadosObject(RGWRadosStore *_st, const rgw_obj_key& _k, RGWBucket* _b)
: RGWObject(_k, _b),
store(_st),
attrs(),
acls() {
}
RGWRadosObject(const RGWRadosObject& _o) = default;
RGWRadosObject(RGWRadosObject& _o) = default;
int read(off_t offset, off_t length, std::iostream& stream) { return length; }
int write(off_t offset, off_t length, std::iostream& stream) { return length; }
RGWAttrs& get_attrs(void) { return attrs; }
int set_attrs(RGWAttrs& a) { attrs = a; return 0; }
int delete_object(void) { return 0; }
virtual int delete_object(RGWObjectCtx* obj_ctx, ACLOwner obj_owner,
ACLOwner bucket_owner, ceph::real_time unmod_since,
bool high_precision_time, uint64_t epoch,
std::string& version_id,optional_yield y) override;
RGWAccessControlPolicy& get_acl(void) { return acls; }
int set_acl(const RGWAccessControlPolicy& acl) { acls = acl; return 0; }
virtual void set_atomic(RGWObjectCtx *rctx) const;
virtual void set_prefetch_data(RGWObjectCtx *rctx);
virtual int get_obj_state(RGWObjectCtx *rctx, RGWBucket& bucket, RGWObjState **state, optional_yield y, bool follow_olh = true);
virtual int get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj *target_obj = nullptr);
virtual int modify_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, bufferlist& attr_val, optional_yield y);
virtual int delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y);
virtual int copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket, RGWObject* dest_obj, uint16_t olh_epoch, std::string* petag, const DoutPrefixProvider *dpp, optional_yield y);
virtual int get_obj_state(RGWObjectCtx *rctx, RGWBucket& bucket, RGWObjState **state, optional_yield y, bool follow_olh = true) override;
virtual int set_obj_attrs(RGWObjectCtx* rctx, RGWAttrs* setattrs, RGWAttrs* delattrs, optional_yield y, rgw_obj* target_obj = NULL) override;
virtual int get_obj_attrs(RGWObjectCtx *rctx, optional_yield y, rgw_obj* target_obj = NULL) override;
virtual int modify_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, bufferlist& attr_val, optional_yield y) override;
virtual int delete_obj_attrs(RGWObjectCtx *rctx, const char *attr_name, optional_yield y) override;
virtual int copy_obj_data(RGWObjectCtx& rctx, RGWBucket* dest_bucket, RGWObject* dest_obj, uint16_t olh_epoch, std::string* petag, const DoutPrefixProvider *dpp, optional_yield y) override;
virtual bool is_expired() override;
virtual void gen_rand_obj_instance_name() override;
virtual std::unique_ptr<RGWObject> clone() {
return std::unique_ptr<RGWObject>(new RGWRadosObject(*this));
}
/* OPs */
virtual std::unique_ptr<ReadOp> get_read_op(RGWObjectCtx *) override;
/* OMAP */
virtual int omap_get_vals_by_keys(const std::string& oid,
const std::set<std::string>& keys,
std::map<std::string, bufferlist> *vals) override;
private:
int read_attrs(RGWRados::Object::Read &read_op, optional_yield y, rgw_obj *target_obj = nullptr);
};
@ -441,8 +567,9 @@ class RGWRadosBucket : public RGWBucket {
virtual int load_by_name(const std::string& tenant, const std::string& bucket_name, const std::string bucket_instance_id, RGWSysObjectCtx *rctx, optional_yield y) override;
virtual std::unique_ptr<RGWObject> get_object(const rgw_obj_key& k) override;
RGWBucketList* list(void) { return new RGWBucketList(); }
virtual int list(ListParams&, int, ListResults&, optional_yield y) override;
RGWObject* create_object(const rgw_obj_key& key /* Attributes */) override;
virtual int remove_bucket(bool delete_children, std::string prefix, std::string delimiter, optional_yield y) override;
virtual int remove_bucket(bool delete_children, std::string prefix, std::string delimiter, bool forward_to_master, req_info* req_info, optional_yield y) override;
RGWAccessControlPolicy& get_acl(void) { return acls; }
virtual int set_acl(RGWAccessControlPolicy& acl, optional_yield y) override;
virtual int get_bucket_info(optional_yield y) override;
@ -461,7 +588,9 @@ class RGWRadosBucket : public RGWBucket {
virtual int put_instance_info(bool exclusive, ceph::real_time mtime) override;
virtual bool is_owner(RGWUser* user) override;
virtual int check_empty(optional_yield y) override;
virtual int check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size) override;
virtual int check_quota(RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size, bool check_size_only = false) override;
virtual int set_instance_attrs(RGWAttrs& attrs, optional_yield y) override;
virtual int try_refresh_info(ceph::real_time *pmtime) override;
virtual std::unique_ptr<RGWBucket> clone() {
return std::unique_ptr<RGWBucket>(new RGWRadosBucket(*this));
}
@ -488,9 +617,9 @@ class RGWRadosStore : public RGWStore {
virtual int get_bucket(RGWUser* u, const RGWBucketInfo& i, std::unique_ptr<RGWBucket>* bucket) override;
virtual int get_bucket(RGWUser* u, const std::string& tenant, const std::string&name, std::unique_ptr<RGWBucket>* bucket) override;
virtual int create_bucket(RGWUser& u, const rgw_bucket& b,
const string& zonegroup_id,
const rgw_placement_rule& placement_rule,
const string& swift_ver_location,
const std::string& zonegroup_id,
rgw_placement_rule& placement_rule,
std::string& swift_ver_location,
const RGWQuotaInfo * pquota_info,
map<std::string, bufferlist>& attrs,
RGWBucketInfo& info,
@ -501,12 +630,17 @@ class RGWRadosStore : public RGWStore {
req_info& req_info,
std::unique_ptr<RGWBucket>* bucket);
virtual RGWBucketList* list_buckets(void) { return new RGWBucketList(); }
virtual bool is_meta_master() override;
virtual int forward_request_to_master(RGWUser* user, obj_version *objv,
bufferlist& in_data, JSONParser *jp, req_info& info) override;
void setRados(RGWRados * st) { rados = st; }
RGWRados *getRados(void) { return rados; }
RGWServices *svc() { return &rados->svc; }
const RGWServices *svc() const { return &rados->svc; }
RGWCtl *ctl() { return &rados->ctl; }
const RGWCtl *ctl() const { return &rados->ctl; }
void setUserCtl(RGWUserCtl *_ctl) { user_ctl = _ctl; }
@ -514,15 +648,15 @@ class RGWRadosStore : public RGWStore {
virtual CephContext *ctx(void) { return rados->ctx(); }
int get_obj_head_ioctx(const RGWBucketInfo& bucket_info, const rgw_obj& obj,
librados::IoCtx *ioctx);
// implements DoutPrefixProvider
std::ostream& gen_prefix(std::ostream& out) const { return out << "RGWRadosStore "; }
CephContext* get_cct() const override { return rados->ctx(); }
unsigned get_subsys() const override { return ceph_subsys_rgw; }
private:
int forward_request_to_master(RGWUser* user, obj_version *objv,
bufferlist& in_data, JSONParser *jp, req_info& info);
};
} } // namespace rgw::sal

View File

@ -42,7 +42,7 @@ void seed::init(struct req_state *p_req, rgw::sal::RGWRadosStore *p_store)
store = p_store;
}
int seed::get_torrent_file(RGWRados::Object::Read &read_op,
int seed::get_torrent_file(rgw::sal::RGWObject* object,
uint64_t &total_len,
ceph::bufferlist &bl_data,
rgw_obj &obj)
@ -69,7 +69,7 @@ int seed::get_torrent_file(RGWRados::Object::Read &read_op,
const set<string> obj_key{RGW_OBJ_TORRENT};
map<string, bufferlist> m;
const int r = read_op.state.cur_ioctx->omap_get_vals_by_keys(oid, obj_key, &m);
const int r = object->omap_get_vals_by_keys(oid, obj_key, &m);
if (r < 0) {
ldout(s->cct, 0) << "ERROR: omap_get_vals_by_keys failed: " << r << dendl;
return r;
@ -248,7 +248,7 @@ int seed::save_torrent_file()
{
int op_ret = 0;
string key = RGW_OBJ_TORRENT;
rgw_obj obj(s->bucket->get_bi(), s->object->get_name());
rgw_obj obj(s->bucket->get_key(), s->object->get_name());
rgw_raw_obj raw_obj;
store->getRados()->obj_to_raw(s->bucket->get_info().placement_rule, obj, &raw_obj);

View File

@ -118,7 +118,7 @@ public:
int get_params();
void init(struct req_state *p_req, rgw::sal::RGWRadosStore *p_store);
int get_torrent_file(RGWRados::Object::Read &read_op,
int get_torrent_file(rgw::sal::RGWObject* object,
uint64_t &total_len,
ceph::bufferlist &bl_data,
rgw_obj &obj);

View File

@ -1889,7 +1889,7 @@ int RGWUser::execute_remove(RGWUserAdminOpState& op_state, std::string *err_msg,
std::string prefix, delimiter;
for (auto it = m.begin(); it != m.end(); ++it) {
ret = it->second->remove_bucket(true, prefix, delimiter, y);
ret = it->second->remove_bucket(true, prefix, delimiter, false, nullptr, y);
if (ret < 0) {
set_err_msg(err_msg, "unable to delete user data");
return ret;
@ -2041,7 +2041,7 @@ int RGWUser::execute_modify(RGWUserAdminOpState& op_state, std::string *err_msg)
vector<rgw_bucket> bucket_names;
for (auto iter = m.begin(); iter != m.end(); ++iter) {
auto& bucket = iter->second;
bucket_names.push_back(bucket->get_bi());
bucket_names.push_back(bucket->get_key());
marker = iter->first;
}