static int log_index_operation(cls_method_context_t hctx, string& obj, RGWModifyOp op,
string& tag, utime_t& timestamp,
- rgw_bucket_entry_ver& ver, RGWPendingState state, uint64_t index_ver)
+ rgw_bucket_entry_ver& ver, RGWPendingState state, uint64_t index_ver,
+ string& max_marker)
{
bufferlist bl;
::encode(entry, bl);
+ if (entry.id > max_marker)
+ max_marker = entry.id;
+
return cls_cxx_map_set_val(hctx, key, &bl);
}
}
if (op.log_op) {
- rc = log_index_operation(hctx, op.name, op.op, op.tag, entry.meta.mtime, entry.ver, info.state, header.ver);
+ rc = log_index_operation(hctx, op.name, op.op, op.tag, entry.meta.mtime,
+ entry.ver, info.state, header.ver, header.max_marker);
if (rc < 0)
return rc;
}
bufferlist op_bl;
if (cancel) {
if (op.log_op) {
- rc = log_index_operation(hctx, op.name, op.op, op.tag, entry.meta.mtime, entry.ver, CLS_RGW_STATE_COMPLETE, header.ver);
+ rc = log_index_operation(hctx, op.name, op.op, op.tag, entry.meta.mtime, entry.ver,
+ CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker);
if (rc < 0)
return rc;
}
}
if (op.log_op) {
- rc = log_index_operation(hctx, op.name, op.op, op.tag, entry.meta.mtime, entry.ver, CLS_RGW_STATE_COMPLETE, header.ver);
+ rc = log_index_operation(hctx, op.name, op.op, op.tag, entry.meta.mtime, entry.ver,
+ CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker);
if (rc < 0)
return rc;
}
if (op.log_op) {
rc = log_index_operation(hctx, op.name, CLS_RGW_OP_DEL, op.tag, remove_entry.meta.mtime,
- remove_entry.ver, CLS_RGW_STATE_COMPLETE, header.ver);
+ remove_entry.ver, CLS_RGW_STATE_COMPLETE, header.ver, header.max_marker);
if (rc < 0)
continue;
}
uint64_t tag_timeout;
uint64_t ver;
uint64_t master_ver;
+ string max_marker;
rgw_bucket_dir_header() : tag_timeout(0), ver(0), master_ver(0) {}
void encode(bufferlist &bl) const {
- ENCODE_START(4, 2, bl);
+ ENCODE_START(5, 2, bl);
::encode(stats, bl);
::encode(tag_timeout, bl);
::encode(ver, bl);
::encode(master_ver, bl);
+ ::encode(max_marker, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator &bl) {
} else {
ver = 0;
}
+ if (struct_v >= 5) {
+ ::decode(max_marker, bl);
+ }
DECODE_FINISH(bl);
}
void dump(Formatter *f) const;
map<RGWObjCategory, RGWBucketStats> stats;
uint64_t bucket_ver, master_ver;
- int ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats);
+ string max_marker;
+ int ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats, &max_marker);
if (ret < 0) {
cerr << "error getting bucket stats ret=" << ret << std::endl;
return ret;
formatter->dump_int("mtime", mtime);
formatter->dump_int("ver", bucket_ver);
formatter->dump_int("master_ver", master_ver);
+ formatter->dump_string("max_marker", max_marker);
dump_bucket_usage(stats, formatter);
formatter->close_section();
uint64_t bucket_ver, master_ver;
- ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats);
+ ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats, NULL);
if (ret < 0)
return ret;
bucket = bucket_info.bucket;
uint64_t bucket_ver, master_ver;
- int ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats);
+ string max_marker;
+ int ret = store->get_bucket_stats(bucket, &bucket_ver, &master_ver, stats, &max_marker);
if (ret < 0) {
cerr << "error getting bucket stats ret=" << ret << std::endl;
return ret;
formatter->dump_int("ver", bucket_ver);
formatter->dump_int("master_ver", master_ver);
formatter->dump_int("mtime", mtime);
+ formatter->dump_string("max_marker", max_marker);
dump_bucket_usage(stats, formatter);
formatter->close_section();
return 0;
}
-int RGWRados::get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_t *master_ver, map<RGWObjCategory, RGWBucketStats>& stats)
+int RGWRados::get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_t *master_ver, map<RGWObjCategory, RGWBucketStats>& stats,
+ string *max_marker)
{
rgw_bucket_dir_header header;
int r = cls_bucket_head(bucket, header);
*bucket_ver = header.ver;
*master_ver = header.master_ver;
+ if (max_marker)
+ *max_marker = header.max_marker;
+
return 0;
}
}
int decode_policy(bufferlist& bl, ACLOwner *owner);
- int get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_t *master_ver, map<RGWObjCategory, RGWBucketStats>& stats);
+ int get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_t *master_ver, map<RGWObjCategory, RGWBucketStats>& stats,
+ string *max_marker);
void get_bucket_instance_entry(rgw_bucket& bucket, string& entry);
void get_bucket_meta_oid(rgw_bucket& bucket, string& oid);
flusher.flush();
}
+void RGWOp_BILog_Info::execute() {
+ string bucket_name = s->info.args.get("bucket"),
+ bucket_instance = s->info.args.get("bucket-instance");
+ RGWBucketInfo bucket_info;
+
+ if (bucket_name.empty() && bucket_instance.empty()) {
+ dout(5) << "ERROR: neither bucket nor bucket instance specified" << dendl;
+ http_ret = -EINVAL;
+ return;
+ }
+
+ if (!bucket_instance.empty()) {
+ http_ret = store->get_bucket_instance_info(NULL, bucket_instance, bucket_info, NULL, NULL);
+ if (http_ret < 0) {
+ dout(5) << "could not get bucket instance info for bucket instance id=" << bucket_instance << dendl;
+ return;
+ }
+ } else { /* !bucket_name.empty() */
+ http_ret = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL, NULL);
+ if (http_ret < 0) {
+ dout(5) << "could not get bucket info for bucket=" << bucket_name << dendl;
+ return;
+ }
+ }
+ map<RGWObjCategory, RGWBucketStats> stats;
+ int ret = store->get_bucket_stats(bucket_info.bucket, &bucket_ver, &master_ver, stats, &max_marker);
+ if (ret < 0 && ret != -ENOENT) {
+ http_ret = ret;
+ return;
+ }
+}
+
+void RGWOp_BILog_Info::send_response() {
+ set_req_state_err(s, http_ret);
+ dump_errno(s);
+ end_header(s);
+
+ if (http_ret < 0)
+ return;
+
+ s->formatter->open_object_section("info");
+ encode_json("bucket_ver", bucket_ver, s->formatter);
+ encode_json("master_ver", master_ver, s->formatter);
+ encode_json("max_marker", max_marker, s->formatter);
+ s->formatter->close_section();
+
+ flusher.flush();
+}
+
void RGWOp_BILog_Delete::execute() {
string bucket_name = s->info.args.get("bucket"),
start_marker = s->info.args.get("start-marker"),
return new RGWOp_MDLog_Info;
}
} else if (type.compare("bucket-index") == 0) {
- return new RGWOp_BILog_List;
+ if (s->info.args.exists("info")) {
+ return new RGWOp_BILog_Info;
+ } else {
+ return new RGWOp_BILog_List;
+ }
} else if (type.compare("data") == 0) {
if (s->info.args.exists("id")) {
if (s->info.args.exists("info")) {
#include "rgw_metadata.h"
class RGWOp_BILog_List : public RGWRESTOp {
- int http_ret;
bool sent_header;
public:
- RGWOp_BILog_List() : http_ret(0), sent_header(false) {}
+ RGWOp_BILog_List() : sent_header(false) {}
~RGWOp_BILog_List() {}
int check_caps(RGWUserCaps& caps) {
virtual void send_response_end();
void execute();
virtual const char *name() {
- return "list bucket index log";
+ return "list_bucket_index_log";
+ }
+};
+
+class RGWOp_BILog_Info : public RGWRESTOp {
+ uint64_t bucket_ver;
+ uint64_t master_ver;
+ string max_marker;
+public:
+ RGWOp_BILog_Info() : bucket_ver(0), master_ver(0) {}
+ ~RGWOp_BILog_Info() {}
+
+ int check_caps(RGWUserCaps& caps) {
+ return caps.check_cap("bilog", RGW_CAP_READ);
+ }
+ int verify_permission() {
+ return check_caps(s->user.caps);
+ }
+ virtual void send_response();
+ void execute();
+ virtual const char *name() {
+ return "bucket_index_log_info";
}
};