#include <boost/circular_buffer.hpp>
#include <boost/container/flat_map.hpp>
+#include "include/scope_guard.h"
#include "common/bounded_key_counter.h"
#include "common/errno.h"
#include "rgw_sync_log_trim.h"
const std::string section;
const std::string start_marker;
MetadataListCallback callback;
- void *handle{nullptr};
int _send_request() override;
public:
: RGWAsyncRadosRequest(caller, cn), cct(cct), mgr(mgr),
section(section), start_marker(start_marker), callback(callback)
{}
- ~AsyncMetadataList() override {
- if (handle) {
- mgr->list_keys_complete(handle);
- }
- }
};
int AsyncMetadataList::_send_request()
{
+ void* handle = nullptr;
+ std::list<std::string> keys;
+ bool truncated{false};
+ std::string marker;
+
// start a listing at the given marker
int r = mgr->list_keys_init(section, start_marker, &handle);
- if (r < 0) {
+ if (r == -EINVAL) {
+ // restart with empty marker below
+ } else if (r < 0) {
ldout(cct, 10) << "failed to init metadata listing: "
<< cpp_strerror(r) << dendl;
return r;
- }
- ldout(cct, 20) << "starting metadata listing at " << start_marker << dendl;
-
- std::list<std::string> keys;
- bool truncated{false};
- std::string marker;
-
- do {
- // get the next key and marker
- r = mgr->list_keys_next(handle, 1, keys, &truncated);
- if (r < 0) {
- ldout(cct, 10) << "failed to list metadata: "
- << cpp_strerror(r) << dendl;
- return r;
- }
- marker = mgr->get_marker(handle);
-
- if (!keys.empty()) {
- ceph_assert(keys.size() == 1);
- auto& key = keys.front();
- if (!callback(std::move(key), std::move(marker))) {
- return 0;
+ } else {
+ ldout(cct, 20) << "starting metadata listing at " << start_marker << dendl;
+
+ // release the handle when scope exits
+ auto g = make_scope_guard([=] { mgr->list_keys_complete(handle); });
+
+ do {
+ // get the next key and marker
+ r = mgr->list_keys_next(handle, 1, keys, &truncated);
+ if (r < 0) {
+ ldout(cct, 10) << "failed to list metadata: "
+ << cpp_strerror(r) << dendl;
+ return r;
}
- }
- } while (truncated);
+ marker = mgr->get_marker(handle);
+
+ if (!keys.empty()) {
+ ceph_assert(keys.size() == 1);
+ auto& key = keys.front();
+ if (!callback(std::move(key), std::move(marker))) {
+ return 0;
+ }
+ }
+ } while (truncated);
- if (start_marker.empty()) {
- // already listed all keys
- return 0;
+ if (start_marker.empty()) {
+ // already listed all keys
+ return 0;
+ }
}
// restart the listing from the beginning (empty marker)
- mgr->list_keys_complete(handle);
handle = nullptr;
r = mgr->list_keys_init(section, "", &handle);
}
ldout(cct, 20) << "restarting metadata listing" << dendl;
+ // release the handle when scope exits
+ auto g = make_scope_guard([=] { mgr->list_keys_complete(handle); });
do {
// get the next key and marker
r = mgr->list_keys_next(handle, 1, keys, &truncated);