#include "rgw_bucket.h"
#include "rgw_user.h"
#include "rgw_string.h"
+#include "rgw_multi.h"
#include "include/rados/librados.hpp"
// until everything is moved from rgw_common
static void dump_mulipart_index_results(list<rgw_obj_index_key>& objs_to_unlink,
Formatter *f)
{
- // make sure that an appropiately titled header has been opened previously
- auto oiter = objs_to_unlink.begin();
-
- f->open_array_section("invalid_multipart_entries");
-
- for ( ; oiter != objs_to_unlink.end(); ++oiter) {
- f->dump_string("object", oiter->name);
+ for (const auto& o : objs_to_unlink) {
+ f->dump_string("object", o.name);
}
-
- f->close_section();
}
void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id,
if (ret < 0)
return ret;
-
RGWRados::Bucket target(store, info);
RGWRados::Bucket::List list_op(&target);
+ CephContext *cct = store->ctx();
+ int max = 1000;
list_op.params.list_versions = true;
- if (delete_children) {
- int max = 1000;
+ do {
+ objs.clear();
+
+ ret = list_op.list_objects(max, &objs, &common_prefixes, NULL);
+ if (ret < 0)
+ return ret;
- do {
- objs.clear();
+ if (!objs.empty() && !delete_children) {
+ lderr(store->ctx()) << "ERROR: could not remove non-empty bucket " << bucket.name << dendl;
+ return -ENOTEMPTY;
+ }
- ret = list_op.list_objects(max, &objs, &common_prefixes, NULL);
+ for (const auto& obj : objs) {
+ rgw_obj_key key(obj.key);
+ ret = rgw_remove_object(store, info, bucket, key);
if (ret < 0)
return ret;
+ }
- std::vector<rgw_bucket_dir_entry>::iterator it = objs.begin();
- for (; it != objs.end(); ++it) {
- rgw_obj_key key(it->key);
- ret = rgw_remove_object(store, info, bucket, key);
- if (ret < 0)
- return ret;
- }
+ } while (!objs.empty());
- } while (!objs.empty());
+ string prefix, delimiter;
+ ret = abort_bucket_multiparts(store, cct, info, prefix, delimiter);
+ if (ret < 0) {
+ return ret;
}
ret = rgw_bucket_sync_user_stats(store, bucket.tenant, info);
map<string, bool> common_prefixes;
RGWBucketInfo info;
RGWObjectCtx obj_ctx(store);
+ CephContext *cct = store->ctx();
string bucket_ver, master_ver;
if (ret < 0)
return ret;
+ string prefix, delimiter;
+
+ ret = abort_bucket_multiparts(store, cct, info, prefix, delimiter);
+ if (ret < 0) {
+ return ret;
+ }
RGWRados::Bucket target(store, info);
RGWRados::Bucket::List list_op(&target);
policy.encode(aclbl);
r = store->system_obj_set_attr(NULL, obj, RGW_ATTR_ACL, aclbl, &objv_tracker);
- if (r < 0)
+ if (r < 0) {
return r;
+ }
RGWAccessControlPolicy policy_instance;
policy_instance.create_default(user_info.user_id, display_name);
string oid_bucket_instance = RGW_BUCKET_INSTANCE_MD_PREFIX + key;
rgw_raw_obj obj_bucket_instance(root_pool, oid_bucket_instance);
r = store->system_obj_set_attr(NULL, obj_bucket_instance, RGW_ATTR_ACL, aclbl, &objv_tracker);
+ if (r < 0) {
+ return r;
+ }
r = rgw_link_bucket(store, user_info.user_id, bucket_info.bucket, real_time());
- if (r < 0)
+ if (r < 0) {
return r;
+ }
}
return 0;
}
int RGWBucket::check_bad_index_multipart(RGWBucketAdminOpState& op_state,
- list<rgw_obj_index_key>& objs_to_unlink, std::string *err_msg)
+ RGWFormatterFlusher& flusher ,std::string *err_msg)
{
bool fix_index = op_state.will_fix_index();
rgw_bucket bucket = op_state.get_bucket();
- int max = 1000;
+ size_t max = 1000;
map<string, bool> common_prefixes;
- string ns = "multipart";
bool is_truncated;
map<string, bool> meta_objs;
map<rgw_obj_index_key, string> all_objs;
RGWRados::Bucket::List list_op(&target);
list_op.params.list_versions = true;
- list_op.params.ns = ns;
+ list_op.params.ns = RGW_OBJ_NS_MULTIPART;
do {
vector<rgw_bucket_dir_entry> result;
} while (is_truncated);
+ list<rgw_obj_index_key> objs_to_unlink;
+ Formatter *f = flusher.get_formatter();
+
+ f->open_array_section("invalid_multipart_entries");
+
for (auto aiter = all_objs.begin(); aiter != all_objs.end(); ++aiter) {
string& name = aiter->second;
if (meta_objs.find(name) == meta_objs.end()) {
objs_to_unlink.push_back(aiter->first);
}
- }
- if (objs_to_unlink.empty())
- return 0;
+ if (objs_to_unlink.size() > max) {
+ if (fix_index) {
+ int r = store->remove_objs_from_index(bucket_info, objs_to_unlink);
+ if (r < 0) {
+ set_err_msg(err_msg, "ERROR: remove_obj_from_index() returned error: " +
+ cpp_strerror(-r));
+ return r;
+ }
+ }
+
+ dump_mulipart_index_results(objs_to_unlink, flusher.get_formatter());
+ flusher.flush();
+ objs_to_unlink.clear();
+ }
+ }
if (fix_index) {
int r = store->remove_objs_from_index(bucket_info, objs_to_unlink);
}
}
+ dump_mulipart_index_results(objs_to_unlink, f);
+ f->close_section();
+ flusher.flush();
+
return 0;
}
RGWFormatterFlusher& flusher)
{
int ret;
- map<string, rgw_bucket_dir_entry> result;
map<RGWObjCategory, RGWStorageStats> existing_stats;
map<RGWObjCategory, RGWStorageStats> calculated_stats;
- list<rgw_obj_index_key> objs_to_unlink;
+
RGWBucket bucket;
Formatter *formatter = flusher.get_formatter();
flusher.start(0);
- ret = bucket.check_bad_index_multipart(op_state, objs_to_unlink);
+ ret = bucket.check_bad_index_multipart(op_state, flusher);
if (ret < 0)
return ret;
- dump_mulipart_index_results(objs_to_unlink, formatter);
- flusher.flush();
-
ret = bucket.check_object_index(op_state, flusher);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
- return bucket.remove(op_state, bypass_gc, keep_index_consistent);
+ std::string err_msg;
+ ret = bucket.remove(op_state, bypass_gc, keep_index_consistent, &err_msg);
+ if (!err_msg.empty()) {
+ lderr(store->ctx()) << "ERROR: " << err_msg << dendl;
+ }
+ return ret;
}
int RGWBucketAdminOp::remove_object(RGWRados *store, RGWBucketAdminOpState& op_state)
bci.info.placement_rule = old_bci.info.placement_rule;
}
+ if (exists && old_bci.info.datasync_flag_enabled() != bci.info.datasync_flag_enabled()) {
+ int shards_num = bci.info.num_shards? bci.info.num_shards : 1;
+ int shard_id = bci.info.num_shards? 0 : -1;
+
+ if (!bci.info.datasync_flag_enabled()) {
+ ret = store->stop_bi_log_entries(bci.info, -1);
+ if (ret < 0) {
+ lderr(store->ctx()) << "ERROR: failed writing bilog" << dendl;
+ return ret;
+ }
+ } else {
+ ret = store->resync_bi_log_entries(bci.info, -1);
+ if (ret < 0) {
+ lderr(store->ctx()) << "ERROR: failed writing bilog" << dendl;
+ return ret;
+ }
+ }
+
+ for (int i = 0; i < shards_num; ++i, ++shard_id) {
+ ret = store->data_log->add_entry(bci.info.bucket, shard_id);
+ if (ret < 0) {
+ lderr(store->ctx()) << "ERROR: failed writing data log" << dendl;
+ return ret;
+ }
+ }
+ }
+
// are we actually going to perform this put, or is it too old?
if (exists &&
!check_versions(old_bci.info.objv_tracker.read_version, orig_mtime,