mirror of
https://github.com/ceph/ceph
synced 2025-02-24 19:47:44 +00:00
Merge pull request #36381 from dang/wip-dang-zipper-7
Zipper 7 - chop list items
This commit is contained in:
commit
e88a413151
@ -4,3 +4,4 @@ overrides:
|
||||
client:
|
||||
setuser: ceph
|
||||
setgroup: ceph
|
||||
debug rgw: 20
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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(),
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 = ⌖
|
||||
|
||||
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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user