From: Yehuda Sadeh Date: Mon, 6 May 2019 21:03:28 +0000 (-0700) Subject: rgw: ctl.bucket: move [un]link bucket into ctl X-Git-Tag: v15.1.0~1898^2^2~82 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=2f915d0aa7315663ef2ea06acb9b8c2d312f4668;p=ceph-ci.git rgw: ctl.bucket: move [un]link bucket into ctl Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 141dc936c1b..8b101cec2e0 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -206,111 +206,6 @@ int rgw_bucket_sync_user_stats(RGWRados *store, const string& tenant_name, const return 0; } -int rgw_link_bucket(RGWRados* const store, - const rgw_user& user_id, - rgw_bucket& bucket, - ceph::real_time creation_time, - bool update_entrypoint) -{ - int ret; - string& tenant_name = bucket.tenant; - string& bucket_name = bucket.name; - - cls_user_bucket_entry new_bucket; - - RGWBucketEntryPoint ep; - RGWObjVersionTracker ot; - - bucket.convert(&new_bucket.bucket); - new_bucket.size = 0; - if (real_clock::is_zero(creation_time)) - new_bucket.creation_time = real_clock::now(); - else - new_bucket.creation_time = creation_time; - - map attrs; - RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx(); - - if (update_entrypoint) { - ret = store->get_bucket_entrypoint_info(obj_ctx, tenant_name, bucket_name, ep, &ot, NULL, &attrs); - if (ret < 0 && ret != -ENOENT) { - ldout(store->ctx(), 0) << "ERROR: store->get_bucket_entrypoint_info() returned: " - << cpp_strerror(-ret) << dendl; - } - } - - string buckets_obj_id; - rgw_get_buckets_obj(user_id, buckets_obj_id); - - rgw_raw_obj obj(store->svc.zone->get_zone_params().user_uid_pool, buckets_obj_id); - ret = store->cls_user_add_bucket(obj, new_bucket); - if (ret < 0) { - ldout(store->ctx(), 0) << "ERROR: error adding bucket to directory: " - << cpp_strerror(-ret) << dendl; - goto done_err; - } - - if (!update_entrypoint) - return 0; - - ep.linked = true; - ep.owner = user_id; - ep.bucket = bucket; - ret = store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, real_time(), &attrs); - if (ret < 0) - goto done_err; - - return 0; -done_err: - int r = rgw_unlink_bucket(store, user_id, bucket.tenant, bucket.name); - if (r < 0) { - ldout(store->ctx(), 0) << "ERROR: failed unlinking bucket on error cleanup: " - << cpp_strerror(-r) << dendl; - } - return ret; -} - -int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id, const string& tenant_name, const string& bucket_name, bool update_entrypoint) -{ - int ret; - - string buckets_obj_id; - rgw_get_buckets_obj(user_id, buckets_obj_id); - - cls_user_bucket bucket; - bucket.name = bucket_name; - rgw_raw_obj obj(store->svc.zone->get_zone_params().user_uid_pool, buckets_obj_id); - ret = store->cls_user_remove_bucket(obj, bucket); - if (ret < 0) { - ldout(store->ctx(), 0) << "ERROR: error removing bucket from directory: " - << cpp_strerror(-ret)<< dendl; - } - - if (!update_entrypoint) - return 0; - - RGWBucketEntryPoint ep; - RGWObjVersionTracker ot; - map attrs; - RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx(); - ret = store->get_bucket_entrypoint_info(obj_ctx, tenant_name, bucket_name, ep, &ot, NULL, &attrs); - if (ret == -ENOENT) - return 0; - if (ret < 0) - return ret; - - if (!ep.linked) - return 0; - - if (ep.owner != user_id) { - ldout(store->ctx(), 0) << "bucket entry point user mismatch, can't unlink bucket: " << ep.owner << " != " << user_id << dendl; - return -EINVAL; - } - - ep.linked = false; - return store->put_bucket_entrypoint_info(tenant_name, bucket_name, ep, false, ot, real_time(), &attrs); -} - int rgw_bucket_parse_bucket_instance(const string& bucket_instance, string *target_bucket_instance, int *shard_id) { ssize_t pos = bucket_instance.rfind(':'); @@ -484,8 +379,8 @@ void check_bad_user_bucket_mapping(RGWRados *store, const rgw_user& user_id, cout << "bucket info mismatch: expected " << actual_bucket << " got " << bucket << std::endl; if (fix) { cout << "fixing" << std::endl; - r = rgw_link_bucket(store, user_id, actual_bucket, - bucket_info.creation_time); + r = store->ctl.bucket->link_bucket(user_id, actual_bucket, + bucket_info.creation_time); if (r < 0) { cerr << "failed to fix bucket: " << cpp_strerror(-r) << std::endl; } @@ -587,7 +482,7 @@ int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children, return ret; } - ret = rgw_unlink_bucket(store, info.owner, bucket.tenant, bucket.name, false); + ret = store->ctl.bucket->unlink_bucket(info.owner, bucket, false); if (ret < 0) { lderr(store->ctx()) << "ERROR: unable to remove user bucket information" << dendl; } @@ -752,7 +647,7 @@ int rgw_remove_bucket_bypass_gc(RGWRados *store, rgw_bucket& bucket, return ret; } - ret = rgw_unlink_bucket(store, info.owner, bucket.tenant, bucket.name, false); + ret = store->ctl.bucket->unlink_bucket(info.owner, bucket, false); if (ret < 0) { lderr(store->ctx()) << "ERROR: unable to remove user bucket information" << dendl; } @@ -849,7 +744,7 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg) return -EIO; } - r = rgw_unlink_bucket(store, owner.get_id(), bucket.tenant, bucket.name, false); + r = store->ctl.bucket->unlink_bucket(owner.get_id(), bucket, false); if (r < 0) { set_err_msg(err_msg, "could not unlink policy from user " + owner.get_id().to_str()); return r; @@ -895,8 +790,9 @@ int RGWBucket::link(RGWBucketAdminOpState& op_state, std::string *err_msg) return r; } - r = rgw_link_bucket(store, user_info.user_id, bucket_info.bucket, - ceph::real_time()); + r = store->ctl.bucket->link_bucket(user_info.user_id, + bucket_info.bucket, + ceph::real_time()); if (r < 0) { return r; } @@ -914,7 +810,7 @@ int RGWBucket::unlink(RGWBucketAdminOpState& op_state, std::string *err_msg) return -EINVAL; } - int r = rgw_unlink_bucket(store, user_info.user_id, bucket.tenant, bucket.name); + int r = store->ctl.bucket->unlink_bucket(user_info.user_id, bucket); if (r < 0) { set_err_msg(err_msg, "error unlinking bucket" + cpp_strerror(-r)); } @@ -2522,8 +2418,14 @@ public: RGWSI_Bucket *bucket{nullptr}; } svc; - RGWBucketMetadataHandler(RGWSI_Bucket *bucket_svc) { + struct Ctl { + RGWBucketCtl *bucket{nullptr}; + } ctl; + + RGWBucketMetadataHandler(RGWSI_Bucket *bucket_svc, + RGWBucketCtl *bucket_ctl) { svc.bucket = bucket_svc; + ctl.bucket = bucket_ctl; be_handler = svc.bucket->get_ep_be_handler(); } @@ -2589,7 +2491,7 @@ public: * it immediately and don't want to invalidate our cached objv_version or the bucket obj removal * will incorrectly fail. */ - ret = rgw_unlink_bucket(store, be.owner, tenant_name, bucket_name, false); + ret = ctl.bucket->unlink_bucket(be.owner, be.bucket, false); if (ret < 0) { lderr(svc.bucket->ctx()) << "could not unlink bucket=" << entry << " owner=" << be.owner << dendl; } @@ -2719,10 +2621,10 @@ int RGWMetadataHandlerPut_Bucket::put_post() /* link bucket */ if (be.linked) { - ret = rgw_link_bucket(store, be.owner, be.bucket, be.creation_time, false); + ret = handler->ctl.bucket->link_bucket(be.owner, be.bucket, be.creation_time, false); } else { - ret = rgw_unlink_bucket(store, be.owner, be.bucket.tenant, - be.bucket.name, false); + ret = handler->ctl.bucket->unlink_bucket(store, be.owner, be.bucket.tenant, + be.bucket.name, false); } return ret; @@ -2873,7 +2775,7 @@ public: /* link new bucket */ - ret = rgw_link_bucket(store, new_be.owner, new_be.bucket, new_be.creation_time, false, y); + ret = ctl.bucket->link_bucket(new_be.owner, new_be.bucket, new_be.creation_time, false, y); if (ret < 0) { ldout(cct, 0) << "ERROR: failed to link new bucket for bucket=" << new_be.bucket << " ret=" << ret << dendl; return ret; @@ -2881,7 +2783,7 @@ public: /* clean up old stuff */ - ret = rgw_unlink_bucket(store, be.owner, tenant_name, bucket_name, false, y); + ret = ctl.bucket->unlink_bucket(be.owner, tenant_name, bucket_name, false, y); if (ret < 0) { lderr(cct) << "could not unlink bucket=" << entry << " owner=" << be.owner << dendl; } @@ -3348,6 +3250,133 @@ int RGWBucketCtl::set_bucket_instance_attrs(RGWBucketInfo& bucket_info, } +int RGWBucketCtl::link_bucket(const rgw_user& user_id, + const rgw_bucket& bucket, + ceph::real_time creation_time, + bool update_entrypoint) +{ + return bucket_be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) { + return do_link_bucket(op, user_id, bucket, creation_time, update_entrypoint); + } +} + +int RGWBucketCtl::do_link_bucket(RGWSI_MetaBackend_Handler::Op *op, + const rgw_user& user_id, + const rgw_bucket& bucket, + ceph::real_time creation_time, + bool update_entrypoint) +{ + int ret; + string& tenant_name = bucket.tenant; + string& bucket_name = bucket.name; + + cls_user_bucket_entry new_bucket; + + RGWBucketEntryPoint ep; + RGWObjVersionTracker ot; + + bucket.convert(&new_bucket.bucket); + new_bucket.size = 0; + if (real_clock::is_zero(creation_time)) + new_bucket.creation_time = real_clock::now(); + else + new_bucket.creation_time = creation_time; + + map attrs; + RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx(); + + if (update_entrypoint) { + ret = svc.bucket->read_bucket_entrypoint_info(op->ctx(), + bucket, &ep, &ot, + nullptr, &attrs); + if (ret < 0 && ret != -ENOENT) { + ldout(store->ctx(), 0) << "ERROR: store->get_bucket_entrypoint_info() returned: " + << cpp_strerror(-ret) << dendl; + } + } + + string buckets_obj_id; + rgw_get_buckets_obj(user_id, buckets_obj_id); + + rgw_raw_obj obj(store->svc.zone->get_zone_params().user_uid_pool, buckets_obj_id); + ret = store->cls_user_add_bucket(obj, new_bucket); + if (ret < 0) { + ldout(store->ctx(), 0) << "ERROR: error adding bucket to directory: " + << cpp_strerror(-ret) << dendl; + goto done_err; + } + + if (!update_entrypoint) + return 0; + + ep.linked = true; + ep.owner = user_id; + ep.bucket = bucket; + ret = svc.bucket->store_bucket_entrypoint_info(op->ctx(), bucket, ep, false, ot, real_time(), &attrs); + if (ret < 0) + goto done_err; + + return 0; +done_err: + int r = do_unlink_bucket(op, user_id, bucket); + if (r < 0) { + ldout(store->ctx(), 0) << "ERROR: failed unlinking bucket on error cleanup: " + << cpp_strerror(-r) << dendl; + } + return ret; +} + +int RGWBucketCtl::unlink_bucket(const rgw_user& user_id, const rgw_bucket, bool update_entrypoint) +{ + return bucket_be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) { + return do_unlink_bucket(op, user_id, bucket, update_entrypoint); + } +} + +int RGWBucketCtl::do_unlink_bucket(RGWSI_MetaBackend_Handler::Op *op, + const rgw_user& user_id, + const rgw_bucket, + bool update_entrypoint) +{ + int ret; + + string buckets_obj_id; + rgw_get_buckets_obj(user_id, buckets_obj_id); + + cls_user_bucket bucket; + bucket.name = bucket_name; + rgw_raw_obj obj(store->svc.zone->get_zone_params().user_uid_pool, buckets_obj_id); + ret = store->cls_user_remove_bucket(obj, bucket); + if (ret < 0) { + ldout(store->ctx(), 0) << "ERROR: error removing bucket from directory: " + << cpp_strerror(-ret)<< dendl; + } + + if (!update_entrypoint) + return 0; + + RGWBucketEntryPoint ep; + RGWObjVersionTracker ot; + map attrs; + RGWSysObjectCtx obj_ctx = store->svc.sysobj->init_obj_ctx(); + ret = svc.bucket->read_bucket_entrypoint_info(op->ctx(), bucket, ep, &ot, NULL, &attrs); + if (ret == -ENOENT) + return 0; + if (ret < 0) + return ret; + + if (!ep.linked) + return 0; + + if (ep.owner != user_id) { + ldout(store->ctx(), 0) << "bucket entry point user mismatch, can't unlink bucket: " << ep.owner << " != " << user_id << dendl; + return -EINVAL; + } + + ep.linked = false; + return svc.bucket->store_bucket_entrypoint_info(op->ctx(), bucket, ep, false, ot, real_time(), &attrs); +} + RGWMetadataHandler *RGWBucketMetaHandlerAllocator::alloc() { return new RGWBucketMetadataHandler; } diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 69f3dc2f883..2faa3db777c 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -211,14 +211,6 @@ extern int rgw_read_user_buckets(RGWRados *store, bool* is_truncated, uint64_t default_amount = 1000); -extern int rgw_link_bucket(RGWRados* store, - const rgw_user& user_id, - rgw_bucket& bucket, - ceph::real_time creation_time, - bool update_entrypoint = true); -extern int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id, - const string& tenant_name, const string& bucket_name, bool update_entrypoint = true); - extern int rgw_remove_object(RGWRados *store, const RGWBucketInfo& bucket_info, const rgw_bucket& bucket, rgw_obj_key& key); extern int rgw_remove_bucket(RGWRados *store, rgw_bucket& bucket, bool delete_children, optional_yield y); extern int rgw_remove_bucket_bypass_gc(RGWRados *store, rgw_bucket& bucket, int concurrent_max, optional_yield y); @@ -592,6 +584,15 @@ class RGWBucketCtl RGWSI_MetaBackend_Handler *bucket_be_handler; /* bucket backend handler */ RGWSI_MetaBackend_Handler *bi_be_handler; /* bucket instance backend handler */ + int do_link_bucket(RGWSI_MetaBackend_Handler::Op *op, + const rgw_bucket& bucket, + ceph::real_time creation_time, + bool update_entrypoint); + + int do_unlink_bucket(RGWSI_MetaBackend_Handler::Op *op, + const rgw_user& user_id, + const rgw_bucket& bucket, + bool update_entrypoint); public: RGWBucketCtl(RGWSI_Zone *zone_svc, RGWSI_Bucket *bucket_svc, @@ -760,6 +761,16 @@ public: int remove_bucket_instance_info(const rgw_bucket& bucket, RGWBucketInfo& info, ceph::optional_ref_default params); + + /* user/bucket */ + int link_bucket(const rgw_user& user_id, + const rgw_bucket& bucket, + ceph::real_time creation_time, + bool update_entrypoint = true); + + int unlink_bucket(const rgw_user& user_id, + const rgw_bucket& bucket, + bool update_entrypoint = true); }; diff --git a/src/rgw/rgw_cr_tools.cc b/src/rgw/rgw_cr_tools.cc index 6a22cb419b6..1d11bbdf95a 100644 --- a/src/rgw/rgw_cr_tools.cc +++ b/src/rgw/rgw_cr_tools.cc @@ -209,11 +209,10 @@ int RGWBucketCreateLocalCR::Request::_send_request() bucket = info.bucket; } - ret = rgw_link_bucket(store, user, bucket, - info.creation_time, false); + ret = store->ctl.bucket->link_bucket(user, bucket, info.creation_time, false); if (ret && !existed && ret != -EEXIST) { /* if it exists (or previously existed), don't remove it! */ - int r = rgw_unlink_bucket(store, user, bucket.tenant, bucket.name); + int r = store->ctl.bucket->unlink_bucket(user, bucket); if (r < 0) { ldout(cct, 0) << "WARNING: failed to unlink bucket: ret=" << r << dendl; } diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 11c810aa892..da8007c7b0d 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -3255,12 +3255,11 @@ void RGWCreateBucket::execute() s->bucket = info.bucket; } - op_ret = rgw_link_bucket(store, s->user->user_id, s->bucket, - info.creation_time, false); + op_ret = store->ctl.bucket->link_bucket(s->user->user_id, s->bucket, + info.creation_time, false); if (op_ret && !existed && op_ret != -EEXIST) { /* if it exists (or previously existed), don't remove it! */ - op_ret = rgw_unlink_bucket(store, s->user->user_id, s->bucket.tenant, - s->bucket.name); + op_ret = store->ctl.bucket->unlink_bucket(s->user->user_id, s->bucket); if (op_ret < 0) { ldpp_dout(this, 0) << "WARNING: failed to unlink bucket: ret=" << op_ret << dendl; @@ -3422,14 +3421,14 @@ void RGWDeleteBucket::execute() if (op_ret == -ECANCELED) { // lost a race, either with mdlog sync or another delete bucket operation. - // in either case, we've already called rgw_unlink_bucket() + // in either case, we've already called ctl.bucket->unlink_bucket() op_ret = 0; return; } if (op_ret == 0) { - op_ret = rgw_unlink_bucket(store, s->bucket_info.owner, s->bucket.tenant, - s->bucket.name, false); + op_ret = store->ctl.bucket->unlink_bucket(s->bucket_info.owner, + s->bucket, false); if (op_ret < 0) { ldpp_dout(this, 0) << "WARNING: failed to unlink bucket: ret=" << op_ret << dendl; @@ -6509,8 +6508,7 @@ bool RGWBulkDelete::Deleter::delete_single(const acct_path_t& path) ret = store->delete_bucket(binfo, ot, s->yield); if (0 == ret) { - ret = rgw_unlink_bucket(store, binfo.owner, binfo.bucket.tenant, - binfo.bucket.name, false); + ret = store->ctl.bucket->unlink_bucket(binfo.owner, binfo.bucket, false); if (ret < 0) { ldpp_dout(s, 0) << "WARNING: failed to unlink bucket: ret=" << ret << dendl; } @@ -6881,12 +6879,11 @@ int RGWBulkUploadOp::handle_dir(const boost::string_ref path) bucket = out_info.bucket; } - op_ret = rgw_link_bucket(store, s->user->user_id, bucket, - out_info.creation_time, false); + op_ret = store->ctl.bucket->link_bucket(s->user->user_id, bucket, + out_info.creation_time, false); if (op_ret && !existed && op_ret != -EEXIST) { /* if it exists (or previously existed), don't remove it! */ - op_ret = rgw_unlink_bucket(store, s->user->user_id, - bucket.tenant, bucket.name); + op_ret = store->ctl.bucket->unlink_bucket(s->user->user_id, bucket); if (op_ret < 0) { ldpp_dout(this, 0) << "WARNING: failed to unlink bucket: ret=" << op_ret << dendl; } diff --git a/src/rgw/rgw_reshard.cc b/src/rgw/rgw_reshard.cc index 33a34858925..0c464252f00 100644 --- a/src/rgw/rgw_reshard.cc +++ b/src/rgw/rgw_reshard.cc @@ -631,7 +631,7 @@ int RGWBucketReshard::do_reshard(int num_shards, return -EIO; } - ret = rgw_link_bucket(store, new_bucket_info.owner, new_bucket_info.bucket, bucket_info.creation_time); + ret = store->ctl.bucket->link_bucket(new_bucket_info.owner, new_bucket_info.bucket, bucket_info.creation_time); if (ret < 0) { lderr(store->ctx()) << "failed to link new bucket instance (bucket_id=" << new_bucket_info.bucket.bucket_id << ": " << cpp_strerror(-ret) << ")" << dendl; return ret;