Fixes: #7110
In dumpling, the bucket info was separated into bucket entry point and
bucket instance objects. When setting bucket attrs we only ended up
updating the bucket instance object. However, pre-dumpling buckets still
keep everything at the entry-point object, so acl changes didn't affect
anything (because we never updated the entry point). This change just
converts the bucket info into the new format.
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
(cherry picked from commit
a5f8cc7ec9ec8bef4fbc656066b4d3a08e5b215b)
return store->meta_mgr->remove_entry(bucket_instance_meta_handler, entry, objv_tracker);
}
-int rgw_bucket_set_attrs(RGWRados *store, rgw_bucket& bucket,
+int rgw_bucket_set_attrs(RGWRados *store, RGWBucketInfo& bucket_info,
map<string, bufferlist>& attrs,
map<string, bufferlist>* rmattrs,
RGWObjVersionTracker *objv_tracker)
{
+ rgw_bucket& bucket = bucket_info.bucket;
+
+ if (!bucket_info.has_instance_obj) {
+ /* an old bucket object, need to convert it */
+ int ret = store->convert_old_bucket_info(NULL, bucket.name);
+ if (ret < 0) {
+ ldout(store->ctx(), 0) << "ERROR: failed converting old bucket info: " << ret << dendl;
+ return ret;
+ }
+ }
string oid;
store->get_bucket_meta_oid(bucket, oid);
rgw_obj obj(store->zone.domain_root, oid);
extern int rgw_remove_object(RGWRados *store, rgw_bucket& bucket, std::string& object);
extern int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children);
-extern int rgw_bucket_set_attrs(RGWRados *store, rgw_bucket& obj,
+extern int rgw_bucket_set_attrs(RGWRados *store, RGWBucketInfo& bucket_info,
map<string, bufferlist>& attrs,
map<string, bufferlist>* rmattrs,
RGWObjVersionTracker *objv_tracker);
if (s->object) {
ret = store->set_attrs(s->obj_ctx, obj, attrs, &rmattrs, ptracker);
} else {
- ret = rgw_bucket_set_attrs(store, obj.bucket, attrs, &rmattrs, ptracker);
+ ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &rmattrs, ptracker);
}
}
if (s->object) {
ret = store->set_attrs(s->obj_ctx, obj, attrs, NULL, ptracker);
} else {
- ret = rgw_bucket_set_attrs(store, obj.bucket, attrs, NULL, ptracker);
+ ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, NULL, ptracker);
}
}
return 0;
}
+int RGWRados::convert_old_bucket_info(void *ctx, string& bucket_name)
+{
+ RGWBucketEntryPoint entry_point;
+ time_t ep_mtime;
+ RGWObjVersionTracker ot;
+ map<string, bufferlist> attrs;
+ RGWBucketInfo info;
+
+ ldout(cct, 10) << "RGWRados::convert_old_bucket_info(): bucket=" << bucket_name << dendl;
+
+ int ret = get_bucket_entrypoint_info(ctx, bucket_name, entry_point, &ot, &ep_mtime, &attrs);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: get_bucket_entrypont_info() returned " << ret << " bucket=" << bucket_name << dendl;
+ return ret;
+ }
+
+ if (!entry_point.has_bucket_info) {
+ /* already converted! */
+ return 0;
+ }
+
+ info = entry_point.old_bucket_info;
+ info.bucket.oid = bucket_name;
+ info.ep_objv = ot.read_version;
+
+ ot.generate_new_write_ver(cct);
+
+ ret = put_linked_bucket_info(info, false, ep_mtime, &ot.write_version, &attrs, true);
+ if (ret < 0) {
+ ldout(cct, 0) << "ERROR: failed to put_linked_bucket_info(): " << ret << dendl;
+ }
+
+ return 0;
+}
+
int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info,
time_t *pmtime, map<string, bufferlist> *pattrs)
{
int get_bucket_instance_info(void *ctx, rgw_bucket& bucket, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
int get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
+ int convert_old_bucket_info(void *ctx, string& bucket_name);
virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info,
time_t *pmtime, map<string, bufferlist> *pattrs = NULL);
virtual int put_linked_bucket_info(RGWBucketInfo& info, bool exclusive, time_t mtime, obj_version *pep_objv,