From 678dac9289ce52f1e5f13e603b5858a3b867c216 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 26 Sep 2016 09:52:29 -0700 Subject: [PATCH] cls/rgw: add bucket_update_stats method Signed-off-by: Yehuda Sadeh (cherry picked from commit 4cc7d3a33a28602b45ec04ff5384e6bc62b376cb) See: http://tracker.ceph.com/issues/17556 See: https://github.com/ceph/ceph/pull/11368 Signed-off-by: Robin H. Johnson --- src/cls/rgw/cls_rgw.cc | 34 ++++++++++++++++++++++++++++++++++ src/cls/rgw/cls_rgw_client.cc | 11 +++++++++++ src/cls/rgw/cls_rgw_client.h | 3 +++ src/cls/rgw/cls_rgw_ops.cc | 23 +++++++++++++++++++++++ src/cls/rgw/cls_rgw_ops.h | 24 ++++++++++++++++++++++++ 5 files changed, 95 insertions(+) diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index 6b62345ab8cd5..83ba5e5d0dde6 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -28,6 +28,7 @@ cls_method_handle_t h_rgw_bucket_set_tag_timeout; cls_method_handle_t h_rgw_bucket_list; cls_method_handle_t h_rgw_bucket_check_index; cls_method_handle_t h_rgw_bucket_rebuild_index; +cls_method_handle_t h_rgw_bucket_update_stats; cls_method_handle_t h_rgw_bucket_prepare_op; cls_method_handle_t h_rgw_bucket_complete_op; cls_method_handle_t h_rgw_bucket_link_olh; @@ -583,6 +584,38 @@ int rgw_bucket_rebuild_index(cls_method_context_t hctx, bufferlist *in, bufferli return write_bucket_header(hctx, &calc_header); } +int rgw_bucket_update_stats(cls_method_context_t hctx, bufferlist *in, bufferlist *out) +{ + // decode request + rgw_cls_bucket_update_stats_op op; + auto iter = in->begin(); + try { + ::decode(op, iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: %s(): failed to decode request\n", __func__); + return -EINVAL; + } + + struct rgw_bucket_dir_header header; + int rc = read_bucket_header(hctx, &header); + if (rc < 0) { + CLS_LOG(1, "ERROR: %s(): failed to read header\n", __func__); + return rc; + } + + for (auto& s : op.stats) { + auto& dest = header.stats[s.first]; + if (op.absolute) { + dest = s.second; + } else { + dest.total_size += s.second.total_size; + dest.total_size_rounded += s.second.total_size_rounded; + dest.num_entries += s.second.num_entries; + } + } + + return write_bucket_header(hctx, &header); +} int rgw_bucket_init_index(cls_method_context_t hctx, bufferlist *in, bufferlist *out) { @@ -3328,6 +3361,7 @@ void __cls_init() cls_register_cxx_method(h_class, "bucket_list", CLS_METHOD_RD, rgw_bucket_list, &h_rgw_bucket_list); cls_register_cxx_method(h_class, "bucket_check_index", CLS_METHOD_RD, rgw_bucket_check_index, &h_rgw_bucket_check_index); cls_register_cxx_method(h_class, "bucket_rebuild_index", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_rebuild_index, &h_rgw_bucket_rebuild_index); + cls_register_cxx_method(h_class, "bucket_update_stats", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_update_stats, &h_rgw_bucket_update_stats); cls_register_cxx_method(h_class, "bucket_prepare_op", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_prepare_op, &h_rgw_bucket_prepare_op); cls_register_cxx_method(h_class, "bucket_complete_op", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_complete_op, &h_rgw_bucket_complete_op); cls_register_cxx_method(h_class, "bucket_link_olh", CLS_METHOD_RD | CLS_METHOD_WR, rgw_bucket_link_olh, &h_rgw_bucket_link_olh); diff --git a/src/cls/rgw/cls_rgw_client.cc b/src/cls/rgw/cls_rgw_client.cc index 220257499a1eb..c1448605e93b5 100644 --- a/src/cls/rgw/cls_rgw_client.cc +++ b/src/cls/rgw/cls_rgw_client.cc @@ -138,6 +138,17 @@ int CLSRGWIssueSetTagTimeout::issue_op(int shard_id, const string& oid) return issue_bucket_set_tag_timeout_op(io_ctx, oid, tag_timeout, &manager); } +void cls_rgw_bucket_update_stats(librados::ObjectWriteOperation& o, bool absolute, + const map& stats) +{ + struct rgw_cls_bucket_update_stats_op call; + call.absolute = absolute; + call.stats = stats; + bufferlist in; + ::encode(call, in); + o.exec("rgw", "bucket_update_stats", in); +} + void cls_rgw_bucket_prepare_op(ObjectWriteOperation& o, RGWModifyOp op, string& tag, const cls_rgw_obj_key& key, const string& locator, bool log_op, uint16_t bilog_flags) diff --git a/src/cls/rgw/cls_rgw_client.h b/src/cls/rgw/cls_rgw_client.h index d691eb8bf5425..ec0b878f77af4 100644 --- a/src/cls/rgw/cls_rgw_client.h +++ b/src/cls/rgw/cls_rgw_client.h @@ -304,6 +304,9 @@ public: CLSRGWConcurrentIO(ioc, _bucket_objs, _max_aio), tag_timeout(_tag_timeout) {} }; +void cls_rgw_bucket_update_stats(librados::ObjectWriteOperation& o, bool absolute, + map& stats); + void cls_rgw_bucket_prepare_op(librados::ObjectWriteOperation& o, RGWModifyOp op, string& tag, const cls_rgw_obj_key& key, const string& locator, bool log_op, uint16_t bilog_op); diff --git a/src/cls/rgw/cls_rgw_ops.cc b/src/cls/rgw/cls_rgw_ops.cc index 2cf361993e838..0b3701bf9ff31 100644 --- a/src/cls/rgw/cls_rgw_ops.cc +++ b/src/cls/rgw/cls_rgw_ops.cc @@ -343,6 +343,29 @@ void rgw_cls_check_index_ret::dump(Formatter *f) const ::encode_json("calculated_header", calculated_header, f); } +void rgw_cls_bucket_update_stats_op::generate_test_instances(list& o) +{ + rgw_cls_bucket_update_stats_op *r = new rgw_cls_bucket_update_stats_op; + r->absolute = true; + rgw_bucket_category_stats& s = r->stats[0]; + s.total_size = 1; + s.total_size_rounded = 4096; + s.num_entries = 1; + o.push_back(r); + + o.push_back(new rgw_cls_bucket_update_stats_op); +} + +void rgw_cls_bucket_update_stats_op::dump(Formatter *f) const +{ + ::encode_json("absolute", absolute, f); + map s; + for (auto& entry : stats) { + s[(int)entry.first] = entry.second; + } + ::encode_json("stats", s, f); +} + void cls_rgw_bi_log_list_op::dump(Formatter *f) const { f->dump_string("marker", marker); diff --git a/src/cls/rgw/cls_rgw_ops.h b/src/cls/rgw/cls_rgw_ops.h index 15a638a392339..90241eb51a134 100644 --- a/src/cls/rgw/cls_rgw_ops.h +++ b/src/cls/rgw/cls_rgw_ops.h @@ -443,6 +443,30 @@ struct rgw_cls_check_index_ret }; WRITE_CLASS_ENCODER(rgw_cls_check_index_ret) +struct rgw_cls_bucket_update_stats_op +{ + bool absolute{false}; + map stats; + + rgw_cls_bucket_update_stats_op() {} + + void encode(bufferlist &bl) const { + ENCODE_START(1, 1, bl); + ::encode(absolute, bl); + ::encode(stats, bl); + ENCODE_FINISH(bl); + } + void decode(bufferlist::iterator &bl) { + DECODE_START(1, bl); + ::decode(absolute, bl); + ::decode(stats, bl); + DECODE_FINISH(bl); + } + void dump(Formatter *f) const; + static void generate_test_instances(list& o); +}; +WRITE_CLASS_ENCODER(rgw_cls_bucket_update_stats_op) + struct rgw_cls_obj_remove_op { list keep_attr_prefixes; -- 2.39.5