map<string, bufferlist> keys;
- string from_index = op.marker;
+ const string& from_index = op.marker;
+ const string& to_index = op.end_marker;
+ const bool to_index_valid = !to_index.empty();
#define MAX_ENTRIES 1000
size_t max_entries = op.max_entries;
if (rc < 0)
return rc;
- CLS_LOG(20, "from_index=%s match_prefix=%s", from_index.c_str(), match_prefix.c_str());
+ CLS_LOG(20, "from_index=%s to_index=%s match_prefix=%s",
+ from_index.c_str(),
+ to_index.c_str(),
+ match_prefix.c_str());
cls_user_list_buckets_ret ret;
list<cls_user_bucket_entry>& entries = ret.entries;
const string& index = iter->first;
marker = index;
+ if (to_index_valid && to_index.compare(index) <= 0)
+ break;
+
bufferlist& bl = iter->second;
bufferlist::iterator biter = bl.begin();
try {
};
void cls_user_bucket_list(librados::ObjectReadOperation& op,
- const string& in_marker, int max_entries, list<cls_user_bucket_entry>& entries,
- string *out_marker, bool *truncated, int *pret)
+ const string& in_marker,
+ const string& end_marker,
+ int max_entries,
+ list<cls_user_bucket_entry>& entries,
+ string *out_marker,
+ bool *truncated,
+ int *pret)
{
bufferlist inbl;
cls_user_list_buckets_op call;
call.marker = in_marker;
+ call.end_marker = end_marker;
call.max_entries = max_entries;
::encode(call, inbl);
void cls_user_complete_stats_sync(librados::ObjectWriteOperation& op);
void cls_user_remove_bucket(librados::ObjectWriteOperation& op, const cls_user_bucket& bucket);
void cls_user_bucket_list(librados::ObjectReadOperation& op,
- const string& in_marker, int max_entries,
+ const string& in_marker,
+ const string& end_marker,
+ int max_entries,
list<cls_user_bucket_entry>& entries,
- string *out_marker, bool *truncated,
+ string *out_marker,
+ bool *truncated,
int *pret);
void cls_user_get_header(librados::ObjectReadOperation& op, cls_user_header *header, int *pret);
int cls_user_get_header_async(librados::IoCtx& io_ctx, string& oid, RGWGetUserHeader_CB *ctx);
struct cls_user_list_buckets_op {
string marker;
+ string end_marker;
int max_entries; /* upperbound to returned num of entries
might return less than that and still be truncated */
: max_entries(0) {}
void encode(bufferlist& bl) const {
- ENCODE_START(1, 1, bl);
+ ENCODE_START(2, 1, bl);
::encode(marker, bl);
::encode(max_entries, bl);
+ ::encode(end_marker, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator& bl) {
- DECODE_START(1, bl);
+ DECODE_START(2, bl);
::decode(marker, bl);
::decode(max_entries, bl);
+ if (struct_v >= 2) {
+ ::decode(end_marker, bl);
+ }
DECODE_FINISH(bl);
}
const string& marker,
uint64_t max,
bool need_stats,
- uint64_t default_amount)
+ uint64_t default_amount,
+ string end_marker)
{
int ret;
buckets.clear();
}
do {
- ret = store->cls_user_list_buckets(obj, m, max - total, entries, &m, &truncated);
+ ret = store->cls_user_list_buckets(obj, m, end_marker, max - total, entries, &m, &truncated);
if (ret == -ENOENT)
ret = 0;
const string& marker,
uint64_t max,
bool need_stats,
- uint64_t default_amount = 1000);
+ uint64_t default_amount = 1000,
+ string end_marker = string());
extern int rgw_link_bucket(RGWRados *store, const rgw_user& user_id, rgw_bucket& bucket, time_t creation_time, bool update_entrypoint = true);
extern int rgw_unlink_bucket(RGWRados *store, const rgw_user& user_id,
}
ret = rgw_read_user_buckets(store, s->user.user_id, buckets,
- marker, read_count, should_get_stats(), 0);
+ marker, read_count, should_get_stats(), 0, end_marker);
if (ret < 0) {
/* hmm.. something wrong here.. the user was authenticated, so it
int ret;
bool sent_data;
string marker;
- int64_t limit;
+ string end_marker;
+ uint64_t limit;
uint64_t limit_max;
uint32_t buckets_count;
uint64_t buckets_objcount;
}
int RGWRados::cls_user_list_buckets(rgw_obj& obj,
- const string& in_marker, int max_entries,
+ const string& in_marker,
+ const string& end_marker,
+ const int max_entries,
list<cls_user_bucket_entry>& entries,
- string *out_marker, bool *truncated)
+ string * const out_marker,
+ bool * const truncated)
{
rgw_rados_ref ref;
rgw_bucket bucket;
librados::ObjectReadOperation op;
int rc;
- cls_user_bucket_list(op, in_marker, max_entries, entries, out_marker, truncated, &rc);
+ cls_user_bucket_list(op, in_marker, end_marker, max_entries, entries, out_marker, truncated, &rc);
bufferlist ibl;
r = ref.ioctx.operate(ref.oid, &op, &ibl);
if (r < 0)
int cls_user_sync_bucket_stats(rgw_obj& user_obj, rgw_bucket& bucket);
int update_user_bucket_stats(const string& user_id, rgw_bucket& bucket, RGWStorageStats& stats);
int cls_user_list_buckets(rgw_obj& obj,
- const string& in_marker, int max_entries,
+ const string& in_marker,
+ const string& end_marker,
+ int max_entries,
list<cls_user_bucket_entry>& entries,
- string *out_marker, bool *truncated);
+ string *out_marker,
+ bool *truncated);
int cls_user_add_bucket(rgw_obj& obj, const cls_user_bucket_entry& entry);
int cls_user_update_buckets(rgw_obj& obj, list<cls_user_bucket_entry>& entries, bool add);
int cls_user_complete_stats_sync(rgw_obj& obj);
int RGWListBuckets_ObjStore_SWIFT::get_params()
{
marker = s->info.args.get("marker");
+ end_marker = s->info.args.get("end_marker");
string limit_str = s->info.args.get("limit");
if (!limit_str.empty()) {