rgw_lua_background.cc
rgw_data_access.cc
driver/rados/account.cc
+ driver/rados/buckets.cc
driver/rados/cls_fifo_legacy.cc
driver/rados/rgw_bucket.cc
driver/rados/rgw_bucket_sync.cc
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright contributors to the Ceph project
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include "buckets.h"
+#include "include/rados/librados.hpp"
+#include "common/async/yield_context.h"
+#include "common/dout.h"
+#include "cls/user/cls_user_client.h"
+#include "rgw_common.h"
+#include "rgw_sal.h"
+#include "rgw_tools.h"
+
+namespace rgwrados::buckets {
+
+static int set(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj,
+ cls_user_bucket_entry&& entry, bool add)
+{
+ std::list<cls_user_bucket_entry> entries;
+ entries.push_back(std::move(entry));
+
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectWriteOperation op;
+ ::cls_user_set_buckets(op, entries, add);
+ return ref.operate(dpp, &op, y);
+}
+
+int add(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj,
+ const rgw_bucket& bucket, ceph::real_time creation_time)
+{
+ cls_user_bucket_entry entry;
+ bucket.convert(&entry.bucket);
+
+ if (ceph::real_clock::is_zero(creation_time)) {
+ entry.creation_time = ceph::real_clock::now();
+ } else {
+ entry.creation_time = creation_time;
+ }
+
+ constexpr bool add = true; // create/update entry
+ return set(dpp, y, rados, obj, std::move(entry), add);
+}
+
+int remove(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj,
+ const rgw_bucket& bucket)
+{
+ cls_user_bucket clsbucket;
+ bucket.convert(&clsbucket);
+
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectWriteOperation op;
+ ::cls_user_remove_bucket(op, clsbucket);
+ return ref.operate(dpp, &op, y);
+}
+
+int list(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj,
+ const std::string& tenant, const std::string& start_marker,
+ const std::string& end_marker, uint64_t max,
+ rgw::sal::BucketList& listing)
+{
+ listing.buckets.clear();
+
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ std::string marker = start_marker;
+ bool truncated = false;
+
+ do {
+ const uint64_t count = max - listing.buckets.size();
+ std::list<cls_user_bucket_entry> entries;
+
+ librados::ObjectReadOperation op;
+ int rc = 0;
+ ::cls_user_bucket_list(op, marker, end_marker, count,
+ entries, &marker, &truncated, &rc);
+
+ bufferlist bl;
+ int r = ref.operate(dpp, &op, &bl, y);
+ if (r == -ENOENT) {
+ listing.next_marker.clear();
+ return 0;
+ }
+ if (r < 0) {
+ return r;
+ }
+ if (rc < 0) {
+ return rc;
+ }
+
+ for (auto& entry : entries) {
+ RGWBucketEnt ent;
+ ent.bucket.tenant = tenant;
+ ent.bucket.name = std::move(entry.bucket.name);
+ ent.bucket.marker = std::move(entry.bucket.marker);
+ ent.bucket.bucket_id = std::move(entry.bucket.bucket_id);
+ ent.size = entry.size;
+ ent.size_rounded = entry.size_rounded;
+ ent.creation_time = entry.creation_time;
+ ent.count = entry.count;
+
+ listing.buckets.push_back(std::move(ent));
+ }
+ } while (truncated && listing.buckets.size() < max);
+
+ if (truncated) {
+ listing.next_marker = std::move(marker);
+ } else {
+ listing.next_marker.clear();
+ }
+ return 0;
+}
+
+int write_stats(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj,
+ const RGWBucketEnt& ent)
+{
+ cls_user_bucket_entry entry;
+ ent.convert(&entry);
+
+ constexpr bool add = false; // bucket entry must exist
+ return set(dpp, y, rados, obj, std::move(entry), add);
+}
+
+int read_stats(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj,
+ RGWStorageStats& stats, ceph::real_time* last_synced,
+ ceph::real_time* last_updated)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectReadOperation op;
+ cls_user_header header;
+ ::cls_user_get_header(op, &header, nullptr);
+
+ bufferlist bl;
+ r = ref.operate(dpp, &op, &bl, y);
+ if (r < 0 && r != -ENOENT) {
+ return r;
+ }
+
+ stats.size = header.stats.total_bytes;
+ stats.size_rounded = header.stats.total_bytes_rounded;
+ stats.num_objects = header.stats.total_entries;
+ if (last_synced) {
+ *last_synced = header.last_stats_sync;
+ }
+ if (last_updated) {
+ *last_updated = header.last_stats_update;
+ }
+ return 0;
+}
+
+// callback wrapper for cls_user_get_header_async()
+class AsyncHeaderCB : public RGWGetUserHeader_CB {
+ boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb;
+ public:
+ explicit AsyncHeaderCB(boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb)
+ : cb(std::move(cb)) {}
+
+ void handle_response(int r, cls_user_header& header) override {
+ const cls_user_stats& hs = header.stats;
+ RGWStorageStats stats;
+ stats.size = hs.total_bytes;
+ stats.size_rounded = hs.total_bytes_rounded;
+ stats.num_objects = hs.total_entries;
+ cb->handle_response(r, stats);
+ cb.reset();
+ }
+};
+
+int read_stats_async(const DoutPrefixProvider* dpp,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ auto headercb = std::make_unique<AsyncHeaderCB>(std::move(cb));
+ r = ::cls_user_get_header_async(ref.ioctx, ref.obj.oid, headercb.get());
+ if (r >= 0) {
+ headercb.release(); // release ownership, handle_response() will free
+ }
+ return r;
+}
+
+int reset_stats(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ int rval;
+
+ cls_user_reset_stats2_op call;
+ cls_user_reset_stats2_ret ret;
+
+ do {
+ buffer::list in, out;
+ librados::ObjectWriteOperation op;
+
+ call.time = ceph::real_clock::now();
+ ret.update_call(call);
+
+ encode(call, in);
+ op.exec("user", "reset_user_stats2", in, &out, &rval);
+ r = ref.operate(dpp, &op, y, librados::OPERATION_RETURNVEC);
+ if (r < 0) {
+ return r;
+ }
+ try {
+ auto bliter = out.cbegin();
+ decode(ret, bliter);
+ } catch (ceph::buffer::error& err) {
+ return -EINVAL;
+ }
+ } while (ret.truncated);
+
+ return rval;
+}
+
+int complete_flush_stats(const DoutPrefixProvider* dpp, optional_yield y,
+ librados::Rados& rados, const rgw_raw_obj& obj)
+{
+ rgw_rados_ref ref;
+ int r = rgw_get_rados_ref(dpp, &rados, obj, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ librados::ObjectWriteOperation op;
+ ::cls_user_complete_stats_sync(op);
+ return ref.operate(dpp, &op, y);
+}
+
+} // namespace rgwrados::buckets
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright contributors to the Ceph project
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include <boost/intrusive_ptr.hpp>
+#include "include/rados/librados_fwd.hpp"
+#include "common/ceph_time.h"
+#include "rgw_sal_fwd.h"
+
+class DoutPrefixProvider;
+class optional_yield;
+struct rgw_bucket;
+struct rgw_raw_obj;
+struct RGWBucketEnt;
+struct RGWStorageStats;
+
+/// Interface for bucket owners (users or accounts) to manage
+/// their list of buckets and storage stats with cls_user.
+namespace rgwrados::buckets {
+
+/// Add the given bucket to the list.
+int add(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const rgw_bucket& bucket,
+ ceph::real_time creation_time);
+
+/// Remove the given bucket from the list.
+int remove(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const rgw_bucket& bucket);
+
+/// Return a paginated list of buckets.
+int list(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const std::string& tenant,
+ const std::string& marker,
+ const std::string& end_marker,
+ uint64_t max,
+ rgw::sal::BucketList& buckets);
+
+/// Update usage stats for the given bucket.
+int write_stats(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ const RGWBucketEnt& bucket);
+
+/// Read the total usage stats of all buckets.
+int read_stats(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ RGWStorageStats& stats,
+ ceph::real_time* last_synced,
+ ceph::real_time* last_updated);
+
+/// Read the total usage stats of all buckets asynchronously.
+int read_stats_async(const DoutPrefixProvider* dpp,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj,
+ boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb);
+
+/// Recalculate the sum of bucket usage.
+int reset_stats(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj);
+
+/// Update the last_synced timestamp.
+int complete_flush_stats(const DoutPrefixProvider* dpp,
+ optional_yield y,
+ librados::Rados& rados,
+ const rgw_raw_obj& obj);
+
+} // namespace rgwrados::buckets
namespace rgw::cls::fifo {
namespace cb = ceph::buffer;
-namespace fifo = rados::cls::fifo;
+namespace fifo = ::rados::cls::fifo;
namespace lr = librados;
inline constexpr std::uint64_t default_max_part_size = 4 * 1024 * 1024;
});
}
-int RGWBucketCtl::read_buckets_stats(map<string, RGWBucketEnt>& m,
+int RGWBucketCtl::read_buckets_stats(std::vector<RGWBucketEnt>& buckets,
optional_yield y, const DoutPrefixProvider *dpp)
{
return call([&](RGWSI_Bucket_X_Ctx& ctx) {
- return svc.bucket->read_buckets_stats(ctx, m, y, dpp);
+ return svc.bucket->read_buckets_stats(ctx, buckets, y, dpp);
});
}
const DoutPrefixProvider *dpp,
bool update_entrypoint = true);
- int read_buckets_stats(std::map<std::string, RGWBucketEnt>& m,
+ int read_buckets_stats(std::vector<RGWBucketEnt>& buckets,
optional_yield y,
const DoutPrefixProvider *dpp);
const std::string& end_marker, uint64_t max, bool need_stats,
BucketList &result, optional_yield y)
{
- RGWUserBuckets ulist;
- bool is_truncated = false;
-
- int ret = store->ctl()->user->list_buckets(dpp, get_id(), marker, end_marker,
- max, need_stats, &ulist,
- &is_truncated, y);
- if (ret < 0)
- return ret;
-
- result.buckets.clear();
-
- for (auto& ent : ulist.get_buckets()) {
- result.buckets.push_back(std::move(ent.second));
- }
-
- if (is_truncated && !result.buckets.empty()) {
- result.next_marker = result.buckets.back().bucket.name;
- } else {
- result.next_marker.clear();
- }
- return 0;
+ return store->ctl()->user->list_buckets(dpp, get_id(), marker, end_marker,
+ max, need_stats, result, y);
}
int RadosBucket::create(const DoutPrefixProvider* dpp,
const string& end_marker,
uint64_t max,
bool need_stats,
- RGWUserBuckets *buckets,
- bool *is_truncated,
+ rgw::sal::BucketList& listing,
optional_yield y,
uint64_t default_max)
{
}
int ret = svc.user->list_buckets(dpp, user, marker, end_marker,
- max, buckets, is_truncated, y);
+ max, listing, y);
if (ret < 0) {
return ret;
}
if (need_stats) {
- map<string, RGWBucketEnt>& m = buckets->get_buckets();
- ret = ctl.bucket->read_buckets_stats(m, y, dpp);
+ ret = ctl.bucket->read_buckets_stats(listing.buckets, y, dpp);
if (ret < 0 && ret != -ENOENT) {
ldpp_dout(dpp, 0) << "ERROR: could not get stats for buckets" << dendl;
return ret;
const std::string& end_marker,
uint64_t max,
bool need_stats,
- RGWUserBuckets *buckets,
- bool *is_truncated,
+ rgw::sal::BucketList& listing,
optional_yield y,
uint64_t default_max = 1000);
const DoutPrefixProvider *dpp) = 0;
virtual int read_buckets_stats(RGWSI_Bucket_X_Ctx& ctx,
- std::map<std::string, RGWBucketEnt>& m,
+ std::vector<RGWBucketEnt>& buckets,
optional_yield y,
const DoutPrefixProvider *dpp) = 0;
};
}
int RGWSI_Bucket_SObj::read_buckets_stats(RGWSI_Bucket_X_Ctx& ctx,
- map<string, RGWBucketEnt>& m,
+ std::vector<RGWBucketEnt>& buckets,
optional_yield y,
const DoutPrefixProvider *dpp)
{
- map<string, RGWBucketEnt>::iterator iter;
- for (iter = m.begin(); iter != m.end(); ++iter) {
- RGWBucketEnt& ent = iter->second;
+ for (auto& ent : buckets) {
int r = read_bucket_stats(ctx, ent.bucket, &ent, y, dpp);
if (r < 0) {
ldpp_dout(dpp, 0) << "ERROR: " << __func__ << "(): read_bucket_stats returned r=" << r << dendl;
}
}
- return m.size();
+ return buckets.size();
}
const DoutPrefixProvider *dpp) override;
int read_buckets_stats(RGWSI_Bucket_X_Ctx& ctx,
- std::map<std::string, RGWBucketEnt>& m,
+ std::vector<RGWBucketEnt>& buckets,
optional_yield y,
const DoutPrefixProvider *dpp) override;
};
const std::string& marker,
const std::string& end_marker,
uint64_t max,
- RGWUserBuckets *buckets,
- bool *is_truncated,
+ rgw::sal::BucketList& listing,
optional_yield y) = 0;
virtual int flush_bucket_stats(const DoutPrefixProvider *dpp,
#include "rgw_zone.h"
#include "rgw_rados.h"
-#include "cls/user/cls_user_client.h"
+#include "driver/rados/buckets.h"
#define dout_subsys ceph_subsys_rgw
info, objv_tracker, pmtime, y, dpp);
}
-int RGWSI_User_RADOS::cls_user_update_buckets(const DoutPrefixProvider *dpp, rgw_raw_obj& obj, list<cls_user_bucket_entry>& entries, bool add, optional_yield y)
-{
- rgw_rados_ref rados_obj;
- int r = rgw_get_rados_ref(dpp, rados, obj, &rados_obj);
- if (r < 0) {
- return r;
- }
-
- librados::ObjectWriteOperation op;
- cls_user_set_buckets(op, entries, add);
- r = rados_obj.operate(dpp, &op, y);
- if (r < 0) {
- return r;
- }
-
- return 0;
-}
-
-int RGWSI_User_RADOS::cls_user_add_bucket(const DoutPrefixProvider *dpp, rgw_raw_obj& obj, const cls_user_bucket_entry& entry, optional_yield y)
-{
- list<cls_user_bucket_entry> l;
- l.push_back(entry);
-
- return cls_user_update_buckets(dpp, obj, l, true, y);
-}
-
-int RGWSI_User_RADOS::cls_user_remove_bucket(const DoutPrefixProvider *dpp, rgw_raw_obj& obj, const cls_user_bucket& bucket, optional_yield y)
-{
- rgw_rados_ref rados_obj;
- int r = rgw_get_rados_ref(dpp, rados, obj, &rados_obj);
- if (r < 0) {
- return r;
- }
-
- librados::ObjectWriteOperation op;
- ::cls_user_remove_bucket(op, bucket);
- r = rados_obj.operate(dpp, &op, y);
- if (r < 0)
- return r;
-
- return 0;
-}
-
int RGWSI_User_RADOS::add_bucket(const DoutPrefixProvider *dpp,
const rgw_user& user,
const rgw_bucket& bucket,
ceph::real_time creation_time,
optional_yield y)
{
- int ret;
-
- cls_user_bucket_entry new_bucket;
-
- 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;
-
rgw_raw_obj obj = get_buckets_obj(user);
- ret = cls_user_add_bucket(dpp, obj, new_bucket, y);
+ int ret = rgwrados::buckets::add(dpp, y, *rados, obj,
+ bucket, creation_time);
if (ret < 0) {
ldpp_dout(dpp, 0) << "ERROR: error adding bucket to user: ret=" << ret << dendl;
return ret;
int RGWSI_User_RADOS::remove_bucket(const DoutPrefixProvider *dpp,
const rgw_user& user,
- const rgw_bucket& _bucket,
+ const rgw_bucket& bucket,
optional_yield y)
{
- cls_user_bucket bucket;
- bucket.name = _bucket.name;
rgw_raw_obj obj = get_buckets_obj(user);
- int ret = cls_user_remove_bucket(dpp, obj, bucket, y);
+ int ret = rgwrados::buckets::remove(dpp, y, *rados, obj, bucket);
if (ret < 0) {
ldpp_dout(dpp, 0) << "ERROR: error removing bucket from user: ret=" << ret << dendl;
}
return 0;
}
-int RGWSI_User_RADOS::cls_user_flush_bucket_stats(const DoutPrefixProvider *dpp,
- rgw_raw_obj& user_obj,
- const RGWBucketEnt& ent, optional_yield y)
-{
- cls_user_bucket_entry entry;
- ent.convert(&entry);
-
- list<cls_user_bucket_entry> entries;
- entries.push_back(entry);
-
- int r = cls_user_update_buckets(dpp, user_obj, entries, false, y);
- if (r < 0) {
- ldpp_dout(dpp, 20) << "cls_user_update_buckets() returned " << r << dendl;
- return r;
- }
-
- return 0;
-}
-
-int RGWSI_User_RADOS::cls_user_list_buckets(const DoutPrefixProvider *dpp,
- rgw_raw_obj& obj,
- const string& in_marker,
- const string& end_marker,
- const int max_entries,
- list<cls_user_bucket_entry>& entries,
- string * const out_marker,
- bool * const truncated,
- optional_yield y)
-{
- rgw_rados_ref rados_obj;
- int r = rgw_get_rados_ref(dpp, rados, obj, &rados_obj);
- if (r < 0) {
- return r;
- }
-
- librados::ObjectReadOperation op;
- int rc;
-
- cls_user_bucket_list(op, in_marker, end_marker, max_entries, entries, out_marker, truncated, &rc);
- bufferlist ibl;
- r = rados_obj.operate(dpp, &op, &ibl, y);
- if (r < 0)
- return r;
- if (rc < 0)
- return rc;
-
- return 0;
-}
-
int RGWSI_User_RADOS::list_buckets(const DoutPrefixProvider *dpp,
const rgw_user& user,
const string& marker,
const string& end_marker,
uint64_t max,
- RGWUserBuckets *buckets,
- bool *is_truncated, optional_yield y)
+ rgw::sal::BucketList& listing,
+ optional_yield y)
{
- int ret;
-
- buckets->clear();
- if (user.id == RGW_USER_ANON_ID) {
+ if (user.id == RGW_USER_ANON_ID) {
ldpp_dout(dpp, 20) << "RGWSI_User_RADOS::list_buckets(): anonymous user" << dendl;
- *is_truncated = false;
+ listing.next_marker.clear();
return 0;
}
- rgw_raw_obj obj = get_buckets_obj(user);
-
- bool truncated = false;
- string m = marker;
-
- uint64_t total = 0;
- do {
- std::list<cls_user_bucket_entry> entries;
- ret = cls_user_list_buckets(dpp, obj, m, end_marker, max - total, entries, &m, &truncated, y);
- if (ret == -ENOENT) {
- ret = 0;
- }
-
- if (ret < 0) {
- return ret;
- }
-
- for (auto& entry : entries) {
- buckets->add(RGWBucketEnt(user, std::move(entry)));
- total++;
- }
-
- } while (truncated && total < max);
-
- if (is_truncated) {
- *is_truncated = truncated;
- }
-
- return 0;
+ rgw_raw_obj obj = get_buckets_obj(user);
+ return rgwrados::buckets::list(dpp, y, *rados, obj, user.tenant,
+ marker, end_marker, max, listing);
}
int RGWSI_User_RADOS::flush_bucket_stats(const DoutPrefixProvider *dpp,
optional_yield y)
{
rgw_raw_obj obj = get_buckets_obj(user);
-
- return cls_user_flush_bucket_stats(dpp, obj, ent, y);
+ return rgwrados::buckets::write_stats(dpp, y, *rados, obj, ent);
}
int RGWSI_User_RADOS::reset_bucket_stats(const DoutPrefixProvider *dpp,
const rgw_user& user,
optional_yield y)
-{
- return cls_user_reset_stats(dpp, user, y);
-}
-
-int RGWSI_User_RADOS::cls_user_reset_stats(const DoutPrefixProvider *dpp, const rgw_user& user, optional_yield y)
{
rgw_raw_obj obj = get_buckets_obj(user);
- rgw_rados_ref rados_obj;
- int r = rgw_get_rados_ref(dpp, rados, obj, &rados_obj);
- if (r < 0) {
- return r;
- }
-
- int rval;
-
- cls_user_reset_stats2_op call;
- cls_user_reset_stats2_ret ret;
-
- do {
- buffer::list in, out;
- librados::ObjectWriteOperation op;
-
- call.time = real_clock::now();
- ret.update_call(call);
-
- encode(call, in);
- op.exec("user", "reset_user_stats2", in, &out, &rval);
- r = rados_obj.operate(dpp, &op, y, librados::OPERATION_RETURNVEC);
- if (r < 0) {
- return r;
- }
- try {
- auto bliter = out.cbegin();
- decode(ret, bliter);
- } catch (ceph::buffer::error& err) {
- return -EINVAL;
- }
- } while (ret.truncated);
-
- return rval;
+ return rgwrados::buckets::reset_stats(dpp, y, *rados, obj);
}
int RGWSI_User_RADOS::complete_flush_stats(const DoutPrefixProvider *dpp,
const rgw_user& user, optional_yield y)
{
rgw_raw_obj obj = get_buckets_obj(user);
- rgw_rados_ref rados_obj;
- int r = rgw_get_rados_ref(dpp, rados, obj, &rados_obj);
- if (r < 0) {
- return r;
- }
-
- librados::ObjectWriteOperation op;
- ::cls_user_complete_stats_sync(op);
- return rados_obj.operate(dpp, &op, y);
-}
-
-int RGWSI_User_RADOS::cls_user_get_header(const DoutPrefixProvider *dpp,
- const rgw_user& user, cls_user_header *header,
- optional_yield y)
-{
- rgw_raw_obj obj = get_buckets_obj(user);
- rgw_rados_ref rados_obj;
- int r = rgw_get_rados_ref(dpp, rados, obj, &rados_obj);
- if (r < 0) {
- return r;
- }
- int rc;
- bufferlist ibl;
- librados::ObjectReadOperation op;
- ::cls_user_get_header(op, header, &rc);
- return rados_obj.operate(dpp, &op, &ibl, y);
-}
-
-int RGWSI_User_RADOS::cls_user_get_header_async(const DoutPrefixProvider *dpp, const string& user_str, RGWGetUserHeader_CB *cb)
-{
- rgw_raw_obj obj = get_buckets_obj(rgw_user(user_str));
- rgw_rados_ref ref;
- int r = rgw_get_rados_ref(dpp, rados, obj, &ref);
- if (r < 0) {
- return r;
- }
-
- r = ::cls_user_get_header_async(ref.ioctx, ref.obj.oid, cb);
- if (r < 0) {
- return r;
- }
-
- return 0;
+ return rgwrados::buckets::complete_flush_stats(dpp, y, *rados, obj);
}
int RGWSI_User_RADOS::read_stats(const DoutPrefixProvider *dpp,
ceph::real_time *last_stats_update,
optional_yield y)
{
- string user_str = user.to_str();
-
- RGWUserInfo info;
- real_time mtime;
- int ret = read_user_info(ctx, user, &info, nullptr, &mtime, nullptr, nullptr, y, dpp);
- if (ret < 0)
- {
- return ret;
- }
-
- cls_user_header header;
- int r = cls_user_get_header(dpp, rgw_user(user_str), &header, y);
- if (r < 0 && r != -ENOENT)
- return r;
-
- const cls_user_stats& hs = header.stats;
-
- stats->size = hs.total_bytes;
- stats->size_rounded = hs.total_bytes_rounded;
- stats->num_objects = hs.total_entries;
-
- if (last_stats_sync) {
- *last_stats_sync = header.last_stats_sync;
- }
-
- if (last_stats_update) {
- *last_stats_update = header.last_stats_update;
- }
-
- return 0;
+ rgw_raw_obj obj = get_buckets_obj(user);
+ return rgwrados::buckets::read_stats(
+ dpp, y, *rados, obj, *stats,
+ last_stats_sync, last_stats_update);
}
-class RGWGetUserStatsContext : public RGWGetUserHeader_CB {
- boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb;
-
-public:
- explicit RGWGetUserStatsContext(boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb)
- : cb(std::move(cb)) {}
-
- void handle_response(int r, cls_user_header& header) override {
- const cls_user_stats& hs = header.stats;
- RGWStorageStats stats;
-
- stats.size = hs.total_bytes;
- stats.size_rounded = hs.total_bytes_rounded;
- stats.num_objects = hs.total_entries;
-
- cb->handle_response(r, stats);
- cb.reset();
- }
-};
-
int RGWSI_User_RADOS::read_stats_async(const DoutPrefixProvider *dpp,
const rgw_user& user,
- boost::intrusive_ptr<rgw::sal::ReadStatsCB> _cb)
+ boost::intrusive_ptr<rgw::sal::ReadStatsCB> cb)
{
- string user_str = user.to_str();
-
- RGWGetUserStatsContext *cb = new RGWGetUserStatsContext(std::move(_cb));
- int r = cls_user_get_header_async(dpp, user_str, cb);
- if (r < 0) {
- delete cb;
- return r;
- }
-
- return 0;
+ rgw_raw_obj obj = get_buckets_obj(user);
+ return rgwrados::buckets::read_stats_async(dpp, *rados, obj, std::move(cb));
}
int remove_email_index(const DoutPrefixProvider *dpp, const std::string& email, optional_yield y);
int remove_swift_name_index(const DoutPrefixProvider *dpp, const std::string& swift_name, optional_yield y);
- /* admin management */
- int cls_user_update_buckets(const DoutPrefixProvider *dpp, rgw_raw_obj& obj, std::list<cls_user_bucket_entry>& entries, bool add, optional_yield y);
- int cls_user_add_bucket(const DoutPrefixProvider *dpp, rgw_raw_obj& obj, const cls_user_bucket_entry& entry, optional_yield y);
- int cls_user_remove_bucket(const DoutPrefixProvider *dpp, rgw_raw_obj& obj, const cls_user_bucket& bucket, optional_yield y);
-
- /* quota stats */
- int cls_user_flush_bucket_stats(const DoutPrefixProvider *dpp, rgw_raw_obj& user_obj,
- const RGWBucketEnt& ent, optional_yield y);
- int cls_user_list_buckets(const DoutPrefixProvider *dpp,
- rgw_raw_obj& obj,
- const std::string& in_marker,
- const std::string& end_marker,
- const int max_entries,
- std::list<cls_user_bucket_entry>& entries,
- std::string * const out_marker,
- bool * const truncated,
- optional_yield y);
-
- int cls_user_reset_stats(const DoutPrefixProvider *dpp, const rgw_user& user, optional_yield y);
- int cls_user_get_header(const DoutPrefixProvider *dpp, const rgw_user& user, cls_user_header *header, optional_yield y);
- int cls_user_get_header_async(const DoutPrefixProvider *dpp, const std::string& user, RGWGetUserHeader_CB *cb);
-
int do_start(optional_yield, const DoutPrefixProvider *dpp) override;
public:
librados::Rados* rados{nullptr};
const std::string& marker,
const std::string& end_marker,
uint64_t max,
- RGWUserBuckets *buckets,
- bool *is_truncated,
+ rgw::sal::BucketList& listing,
optional_yield y) override;
/* quota related */