// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab ft=cpp
+#include "include/function2.hpp"
#include "rgw_acl_s3.h"
#include "rgw_tag_s3.h"
#include "services/svc_bucket.h"
#include "services/svc_user.h"
+#include "account.h"
+#include "buckets.h"
#include "rgw_reshard.h"
#include "rgw_pubsub.h"
return 0;
}
-int RGWBucketAdminOp::unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y)
+int RGWBucketAdminOp::unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err)
{
- RGWBucket bucket;
+ auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver);
+ if (!radosdriver) {
+ set_err_msg(err, "rados store only");
+ return -ENOTSUP;
+ }
+ RGWBucket bucket;
int ret = bucket.init(driver, op_state, y, dpp);
if (ret < 0)
return ret;
- return static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->unlink_bucket(op_state.get_user_id(), op_state.get_bucket()->get_info().bucket, y, dpp, true);
+ auto* rados = radosdriver->getRados()->get_rados_handle();
+ return radosdriver->ctl()->bucket->unlink_bucket(*rados, op_state.get_user_id(), op_state.get_bucket()->get_info().bucket, y, dpp, true);
}
int RGWBucketAdminOp::link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, string *err)
set_err_msg(err, "empty user id");
return -EINVAL;
}
+ auto radosdriver = dynamic_cast<rgw::sal::RadosStore*>(driver);
+ if (!radosdriver) {
+ set_err_msg(err, "rados store only");
+ return -ENOTSUP;
+ }
RGWBucket bucket;
int ret = bucket.init(driver, op_state, y, dpp, err);
return -EIO;
}
- int r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->unlink_bucket(owner.id, old_bucket->get_info().bucket, y, dpp, false);
+ auto* rados = radosdriver->getRados()->get_rados_handle();
+ int r = radosdriver->ctl()->bucket->unlink_bucket(*rados, owner.id, old_bucket->get_info().bucket, y, dpp, false);
if (r < 0) {
set_err_msg(err, "could not unlink policy from user " + owner.id.to_str());
return r;
rgw::sal::Attrs ep_attrs;
rgw_ep_info ep_data{ep, ep_attrs};
- r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->link_bucket(op_state.get_user_id(), loc_bucket->get_info().bucket, loc_bucket->get_info().creation_time, y, dpp, true, &ep_data);
+ r = radosdriver->ctl()->bucket->link_bucket(*rados, op_state.get_user_id(), loc_bucket->get_info().bucket, loc_bucket->get_info().creation_time, y, dpp, true, &ep_data);
if (r < 0) {
set_err_msg(err, "failed to relink bucket");
return r;
if (*loc_bucket != *old_bucket) {
// like RGWRados::delete_bucket -- excepting no bucket_index work.
- r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->remove_bucket_entrypoint_info(
+ r = radosdriver->ctl()->bucket->remove_bucket_entrypoint_info(
old_bucket->get_key(), y, dpp,
RGWBucketCtl::Bucket::RemoveParams()
.set_objv_tracker(&ep_data.ep_objv));
set_err_msg(err, "failed to unlink old bucket " + old_bucket->get_tenant() + "/" + old_bucket->get_name());
return r;
}
- r = static_cast<rgw::sal::RadosStore*>(driver)->ctl()->bucket->remove_bucket_instance_info(
+ r = radosdriver->ctl()->bucket->remove_bucket_instance_info(
old_bucket->get_key(), old_bucket->get_info(),
y, dpp,
RGWBucketCtl::BucketInstance::RemoveParams()
class RGWBucketMetadataHandler : public RGWBucketMetadataHandlerBase {
public:
+ librados::Rados& rados;
struct Svc {
RGWSI_Bucket *bucket{nullptr};
} svc;
RGWBucketCtl *bucket{nullptr};
} ctl;
- RGWBucketMetadataHandler() {}
+ explicit RGWBucketMetadataHandler(librados::Rados& rados)
+ : rados(rados) {}
void init(RGWSI_Bucket *bucket_svc,
RGWBucketCtl *bucket_ctl) override {
* it immediately and don't want to invalidate our cached objv_version or the bucket obj removal
* will incorrectly fail.
*/
- ret = ctl.bucket->unlink_bucket(be.owner, be.bucket, y, dpp, false);
+ ret = ctl.bucket->unlink_bucket(rados, be.owner, be.bucket, y, dpp, false);
if (ret < 0) {
ldpp_dout(dpp, -1) << "could not unlink bucket=" << entry << " owner=" << be.owner << dendl;
}
class RGWMetadataHandlerPut_Bucket : public RGWMetadataHandlerPut_SObj
{
RGWBucketMetadataHandler *bhandler;
+ librados::Rados& rados;
RGWBucketEntryMetadataObject *obj;
public:
- RGWMetadataHandlerPut_Bucket(RGWBucketMetadataHandler *_handler,
+ RGWMetadataHandlerPut_Bucket(RGWBucketMetadataHandler *_handler, librados::Rados& rados,
RGWSI_MetaBackend_Handler::Op *op, string& entry,
RGWMetadataObject *_obj, RGWObjVersionTracker& objv_tracker,
optional_yield y,
- RGWMDLogSyncType type, bool from_remote_zone) : RGWMetadataHandlerPut_SObj(_handler, op, entry, _obj, objv_tracker, y, type, from_remote_zone),
- bhandler(_handler) {
- obj = static_cast<RGWBucketEntryMetadataObject *>(_obj);
- }
- ~RGWMetadataHandlerPut_Bucket() {}
+ RGWMDLogSyncType type, bool from_remote_zone)
+ : RGWMetadataHandlerPut_SObj(_handler, op, entry, _obj, objv_tracker, y, type, from_remote_zone),
+ bhandler(_handler),
+ rados(rados),
+ obj(static_cast<RGWBucketEntryMetadataObject *>(_obj))
+ {}
void encode_obj(bufferlist *bl) override {
obj->get_ep().encode(*bl);
const DoutPrefixProvider *dpp,
RGWMDLogSyncType type, bool from_remote_zone)
{
- RGWMetadataHandlerPut_Bucket put_op(this, op, entry, obj, objv_tracker, y, type, from_remote_zone);
+ RGWMetadataHandlerPut_Bucket put_op(this, rados, op, entry, obj, objv_tracker,
+ y, type, from_remote_zone);
return do_put_operate(&put_op, dpp);
}
/* link bucket */
if (be.linked) {
- ret = bhandler->ctl.bucket->link_bucket(be.owner, be.bucket, be.creation_time, y, dpp, false);
+ ret = bhandler->ctl.bucket->link_bucket(rados, be.owner, be.bucket, be.creation_time, y, dpp, false);
} else {
- ret = bhandler->ctl.bucket->unlink_bucket(be.owner, be.bucket, y, dpp, false);
+ ret = bhandler->ctl.bucket->unlink_bucket(rados, be.owner, be.bucket, y, dpp, false);
}
return ret;
class RGWArchiveBucketMetadataHandler : public RGWBucketMetadataHandler {
public:
- RGWArchiveBucketMetadataHandler() {}
+ explicit RGWArchiveBucketMetadataHandler(librados::Rados& rados)
+ : RGWBucketMetadataHandler(rados) {}
int do_remove(RGWSI_MetaBackend_Handler::Op *op, string& entry, RGWObjVersionTracker& objv_tracker,
optional_yield y, const DoutPrefixProvider *dpp) override {
/* link new bucket */
- ret = ctl.bucket->link_bucket(new_be.owner, new_be.bucket, new_be.creation_time, y, dpp, false);
+ ret = ctl.bucket->link_bucket(rados, new_be.owner, new_be.bucket, new_be.creation_time, y, dpp, false);
if (ret < 0) {
ldpp_dout(dpp, 0) << "ERROR: failed to link new bucket for bucket=" << new_be.bucket << " ret=" << ret << dendl;
return ret;
/* clean up old stuff */
- ret = ctl.bucket->unlink_bucket(be.owner, entry_bucket, y, dpp, false);
+ ret = ctl.bucket->unlink_bucket(rados, be.owner, entry_bucket, y, dpp, false);
if (ret < 0) {
ldpp_dout(dpp, -1) << "could not unlink bucket=" << entry << " owner=" << be.owner << dendl;
}
}
-int RGWBucketCtl::link_bucket(const rgw_user& user_id,
+int RGWBucketCtl::link_bucket(librados::Rados& rados,
+ const rgw_owner& owner,
const rgw_bucket& bucket,
ceph::real_time creation_time,
optional_yield y,
rgw_ep_info *pinfo)
{
return bm_handler->call([&](RGWSI_Bucket_EP_Ctx& ctx) {
- return do_link_bucket(ctx, user_id, bucket, creation_time,
+ return do_link_bucket(ctx, rados, owner, bucket, creation_time,
update_entrypoint, pinfo, y, dpp);
});
}
+static rgw_raw_obj get_owner_buckets_obj(RGWSI_User* svc_user,
+ RGWSI_Zone* svc_zone,
+ const rgw_owner& owner)
+{
+ return std::visit(fu2::overload(
+ [&] (const rgw_user& uid) {
+ return svc_user->get_buckets_obj(uid);
+ },
+ [&] (const rgw_account_id& account_id) {
+ const RGWZoneParams& zone = svc_zone->get_zone_params();
+ return rgwrados::account::get_buckets_obj(zone, account_id);
+ }), owner);
+}
+
int RGWBucketCtl::do_link_bucket(RGWSI_Bucket_EP_Ctx& ctx,
- const rgw_user& user_id,
+ librados::Rados& rados,
+ const rgw_owner& owner,
const rgw_bucket& bucket,
ceph::real_time creation_time,
bool update_entrypoint,
}
}
- ret = svc.user->add_bucket(dpp, user_id, bucket, creation_time, y);
+ const auto& buckets_obj = get_owner_buckets_obj(svc.user, svc.zone, owner);
+ ret = rgwrados::buckets::add(dpp, y, rados, buckets_obj,
+ bucket, creation_time);
if (ret < 0) {
- ldpp_dout(dpp, 0) << "ERROR: error adding bucket to user directory:"
- << " user=" << user_id
+ ldpp_dout(dpp, 0) << "ERROR: error adding bucket to owner directory:"
+ << " owner=" << owner
<< " bucket=" << bucket
<< " err=" << cpp_strerror(-ret)
<< dendl;
return 0;
ep.linked = true;
- ep.owner = user_id;
+ ep.owner = owner;
ep.bucket = bucket;
ret = svc.bucket->store_bucket_entrypoint_info(
ctx, meta_key, ep, false, real_time(), pattrs, &rot, y, dpp);
return 0;
done_err:
- int r = do_unlink_bucket(ctx, user_id, bucket, true, y, dpp);
+ int r = do_unlink_bucket(ctx, rados, owner, bucket, true, y, dpp);
if (r < 0) {
ldpp_dout(dpp, 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& bucket, optional_yield y, const DoutPrefixProvider *dpp, bool update_entrypoint)
+int RGWBucketCtl::unlink_bucket(librados::Rados& rados, const rgw_owner& owner,
+ const rgw_bucket& bucket, optional_yield y,
+ const DoutPrefixProvider *dpp, bool update_entrypoint)
{
return bm_handler->call([&](RGWSI_Bucket_EP_Ctx& ctx) {
- return do_unlink_bucket(ctx, user_id, bucket, update_entrypoint, y, dpp);
+ return do_unlink_bucket(ctx, rados, owner, bucket, update_entrypoint, y, dpp);
});
}
int RGWBucketCtl::do_unlink_bucket(RGWSI_Bucket_EP_Ctx& ctx,
- const rgw_user& user_id,
+ librados::Rados& rados,
+ const rgw_owner& owner,
const rgw_bucket& bucket,
bool update_entrypoint,
optional_yield y,
const DoutPrefixProvider *dpp)
{
- int ret = svc.user->remove_bucket(dpp, user_id, bucket, y);
+ const auto& buckets_obj = get_owner_buckets_obj(svc.user, svc.zone, owner);
+ int ret = rgwrados::buckets::remove(dpp, y, rados, buckets_obj, bucket);
if (ret < 0) {
ldpp_dout(dpp, 0) << "ERROR: error removing bucket from directory: "
<< cpp_strerror(-ret)<< dendl;
if (!ep.linked)
return 0;
- if (ep.owner != user_id) {
- ldpp_dout(dpp, 0) << "bucket entry point user mismatch, can't unlink bucket: " << ep.owner << " != " << user_id << dendl;
+ if (ep.owner != owner) {
+ ldpp_dout(dpp, 0) << "bucket entry point owner mismatch, can't unlink bucket: " << ep.owner << " != " << owner << dendl;
return -EINVAL;
}
return handler->bucket_imports_data();
}
-RGWBucketMetadataHandlerBase* RGWBucketMetaHandlerAllocator::alloc()
+RGWBucketMetadataHandlerBase* RGWBucketMetaHandlerAllocator::alloc(librados::Rados& rados)
{
- return new RGWBucketMetadataHandler();
+ return new RGWBucketMetadataHandler(rados);
}
RGWBucketInstanceMetadataHandlerBase* RGWBucketInstanceMetaHandlerAllocator::alloc(rgw::sal::Driver* driver)
return new RGWBucketInstanceMetadataHandler(driver);
}
-RGWBucketMetadataHandlerBase* RGWArchiveBucketMetaHandlerAllocator::alloc()
+RGWBucketMetadataHandlerBase* RGWArchiveBucketMetaHandlerAllocator::alloc(librados::Rados& rados)
{
- return new RGWArchiveBucketMetadataHandler();
+ return new RGWArchiveBucketMetadataHandler(rados);
}
RGWBucketInstanceMetadataHandlerBase* RGWArchiveBucketInstanceMetaHandlerAllocator::alloc(rgw::sal::Driver* driver)
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
+#include "include/rados/librados_fwd.hpp"
#include "include/types.h"
#include "rgw_common.h"
#include "rgw_tools.h"
class RGWBucketMetaHandlerAllocator {
public:
- static RGWBucketMetadataHandlerBase *alloc();
+ static RGWBucketMetadataHandlerBase *alloc(librados::Rados& rados);
};
class RGWBucketInstanceMetaHandlerAllocator {
class RGWArchiveBucketMetaHandlerAllocator {
public:
- static RGWBucketMetadataHandlerBase *alloc();
+ static RGWBucketMetadataHandlerBase *alloc(librados::Rados& rados);
};
class RGWArchiveBucketInstanceMetaHandlerAllocator {
static int dump_s3_policy(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state,
std::ostream& os, const DoutPrefixProvider *dpp, optional_yield y);
- static int unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y);
+ static int unlink(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, std::string *err_msg = nullptr);
static int link(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const DoutPrefixProvider *dpp, optional_yield y, std::string *err_msg = NULL);
static int chown(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, const std::string& marker, const DoutPrefixProvider *dpp, optional_yield y, std::string *err_msg = NULL);
const DoutPrefixProvider *dpp);
/* user/bucket */
- int link_bucket(const rgw_user& user_id,
+ int link_bucket(librados::Rados& rados,
+ const rgw_owner& owner,
const rgw_bucket& bucket,
ceph::real_time creation_time,
optional_yield y,
bool update_entrypoint = true,
rgw_ep_info *pinfo = nullptr);
- int unlink_bucket(const rgw_user& user_id,
+ int unlink_bucket(librados::Rados& rados,
+ const rgw_owner& owner,
const rgw_bucket& bucket,
optional_yield y,
const DoutPrefixProvider *dpp,
const DoutPrefixProvider *dpp);
int do_link_bucket(RGWSI_Bucket_EP_Ctx& ctx,
- const rgw_user& user,
+ librados::Rados& rados,
+ const rgw_owner& owner,
const rgw_bucket& bucket,
ceph::real_time creation_time,
bool update_entrypoint,
const DoutPrefixProvider *dpp);
int do_unlink_bucket(RGWSI_Bucket_EP_Ctx& ctx,
- const rgw_user& user_id,
+ librados::Rados& rados,
+ const rgw_owner& owner,
const rgw_bucket& bucket,
bool update_entrypoint,
optional_yield y,