int max_read = RBD_MAX_KEYS_READ;
vector<snapid_t> snap_ids;
string last_read = RBD_SNAP_KEY_PREFIX;
+ bool more;
do {
set<string> keys;
- r = cls_cxx_map_get_keys(hctx, last_read, max_read, &keys);
+ r = cls_cxx_map_get_keys(hctx, last_read, max_read, &keys, &more);
if (r < 0) {
return r;
}
if (!keys.empty()) {
last_read = *(keys.rbegin());
}
- } while (r == max_read);
+ } while (more);
}
cls_rbd_parent parent;
int max_read = RBD_MAX_KEYS_READ;
vector<snapid_t> snap_ids;
string last_read = RBD_SNAP_KEY_PREFIX;
+ bool more;
do {
set<string> keys;
- r = cls_cxx_map_get_keys(hctx, last_read, max_read, &keys);
+ r = cls_cxx_map_get_keys(hctx, last_read, max_read, &keys, &more);
if (r < 0)
return r;
}
if (!keys.empty())
last_read = *(keys.rbegin());
- } while (r == max_read);
+ } while (more);
uint64_t snap_seq;
r = read_key(hctx, "snap_seq", &snap_seq);
int max_read = RBD_MAX_KEYS_READ;
uint64_t total_read = 0;
string last_read = RBD_SNAP_KEY_PREFIX;
+ bool more;
do {
map<string, bufferlist> vals;
r = cls_cxx_map_get_vals(hctx, last_read, RBD_SNAP_KEY_PREFIX,
- max_read, &vals);
+ max_read, &vals, &more);
if (r < 0)
return r;
if (!vals.empty())
last_read = vals.rbegin()->first;
- } while (r == RBD_MAX_KEYS_READ);
+ } while (more);
// snapshot inherits parent, if any
cls_rbd_parent parent;
int max_read = RBD_MAX_KEYS_READ;
string last_read = RBD_SNAP_KEY_PREFIX;
+ bool more;
do {
map<string, bufferlist> vals;
r = cls_cxx_map_get_vals(hctx, last_read, RBD_SNAP_KEY_PREFIX,
- max_read, &vals);
+ max_read, &vals, &more);
if (r < 0)
return r;
}
if (!vals.empty())
last_read = vals.rbegin()->first;
- } while (r == RBD_MAX_KEYS_READ);
+ } while (more);
key_from_snap_id(src_snap_id, &src_snap_key);
r = read_key(hctx, src_snap_key, &snap_meta);
}
int max_read = RBD_MAX_KEYS_READ;
- int r = max_read;
map<string, string> images;
string last_read = dir_key_for_name(start_after);
+ bool more = true;
- while (r == max_read && images.size() < max_return) {
+ while (more && images.size() < max_return) {
map<string, bufferlist> vals;
CLS_LOG(20, "last_read = '%s'", last_read.c_str());
- r = cls_cxx_map_get_vals(hctx, last_read, RBD_DIR_NAME_KEY_PREFIX,
- max_read, &vals);
+ int r = cls_cxx_map_get_vals(hctx, last_read, RBD_DIR_NAME_KEY_PREFIX,
+ max_read, &vals, &more);
if (r < 0) {
CLS_ERR("error reading directory by name: %s", cpp_strerror(r).c_str());
return r;
map<string, bufferlist> data;
string last_read = metadata_key_for_name(start_after);
int max_read = max_return ? MIN(RBD_MAX_KEYS_READ, max_return) : RBD_MAX_KEYS_READ;
+ bool more;
do {
map<string, bufferlist> raw_data;
int r = cls_cxx_map_get_vals(hctx, last_read, RBD_METADATA_KEY_PREFIX,
- max_read, &raw_data);
+ max_read, &raw_data, &more);
if (r < 0) {
CLS_ERR("failed to read the vals off of disk: %s", cpp_strerror(r).c_str());
return r;
for (; it != raw_data.end(); ++it)
data[metadata_name_from_key(it->first)].swap(it->second);
- if (r < max_read)
+ if (!more)
break;
last_read = raw_data.rbegin()->first;
if (max_return)
max_read = MIN(RBD_MAX_KEYS_READ, max_return - data.size());
- } while (max_read);
+ } while (more);
::encode(data, *out);
return 0;
std::vector<cls::rbd::MirrorPeer> *peers) {
std::string last_read = PEER_KEY_PREFIX;
int max_read = RBD_MAX_KEYS_READ;
- int r = max_read;
- while (r == max_read) {
+ bool more = true;
+ while (more) {
std::map<std::string, bufferlist> vals;
- r = cls_cxx_map_get_vals(hctx, last_read, PEER_KEY_PREFIX.c_str(),
- max_read, &vals);
+ int r = cls_cxx_map_get_vals(hctx, last_read, PEER_KEY_PREFIX.c_str(),
+ max_read, &vals, &more);
if (r < 0) {
CLS_ERR("error reading peers: %s", cpp_strerror(r).c_str());
return r;
map<std::string, cls::rbd::MirrorImageStatus> *mirror_statuses) {
std::string last_read = image_key(start_after);
int max_read = RBD_MAX_KEYS_READ;
- int r = max_read;
+ bool more = true;
- while (r == max_read && mirror_images->size() < max_return) {
+ while (more && mirror_images->size() < max_return) {
std::map<std::string, bufferlist> vals;
CLS_LOG(20, "last_read = '%s'", last_read.c_str());
- r = cls_cxx_map_get_vals(hctx, last_read, IMAGE_KEY_PREFIX, max_read,
- &vals);
+ int r = cls_cxx_map_get_vals(hctx, last_read, IMAGE_KEY_PREFIX, max_read,
+ &vals, &more);
if (r < 0) {
CLS_ERR("error reading mirror image directory by name: %s",
cpp_strerror(r).c_str());
string last_read = IMAGE_KEY_PREFIX;
int max_read = RBD_MAX_KEYS_READ;
- r = max_read;
- while (r == max_read) {
+ bool more = true;
+ while (more) {
map<string, bufferlist> vals;
r = cls_cxx_map_get_vals(hctx, last_read, IMAGE_KEY_PREFIX,
- max_read, &vals);
+ max_read, &vals, &more);
if (r < 0) {
CLS_ERR("error reading mirrored images: %s", cpp_strerror(r).c_str());
return r;
string last_read = STATUS_GLOBAL_KEY_PREFIX;
int max_read = RBD_MAX_KEYS_READ;
- r = max_read;
- while (r == max_read) {
+ bool more = true;
+ while (more) {
map<string, bufferlist> vals;
r = cls_cxx_map_get_vals(hctx, last_read, STATUS_GLOBAL_KEY_PREFIX,
- max_read, &vals);
+ max_read, &vals, &more);
if (r < 0) {
CLS_ERR("error reading mirrored images: %s", cpp_strerror(r).c_str());
return r;
std::vector<std::string> *instance_ids) {
std::string last_read = INSTANCE_KEY_PREFIX;
int max_read = RBD_MAX_KEYS_READ;
- int r = max_read;
- while (r == max_read) {
+ bool more = true;
+ while (more) {
std::map<std::string, bufferlist> vals;
- r = cls_cxx_map_get_vals(hctx, last_read, INSTANCE_KEY_PREFIX.c_str(),
- max_read, &vals);
+ int r = cls_cxx_map_get_vals(hctx, last_read, INSTANCE_KEY_PREFIX.c_str(),
+ max_read, &vals, &more);
if (r < 0) {
if (r != -ENOENT) {
CLS_ERR("error reading mirror instances: %s", cpp_strerror(r).c_str());
}
int max_read = RBD_MAX_KEYS_READ;
- int r = max_read;
+ bool more = true;
std::map<std::string, std::string> mirror_images;
std::string last_read = mirror::image_key(start_after);
- while (r == max_read && mirror_images.size() < max_return) {
+ while (more && mirror_images.size() < max_return) {
std::map<std::string, bufferlist> vals;
CLS_LOG(20, "last_read = '%s'", last_read.c_str());
- r = cls_cxx_map_get_vals(hctx, last_read, mirror::IMAGE_KEY_PREFIX,
- max_read, &vals);
+ int r = cls_cxx_map_get_vals(hctx, last_read, mirror::IMAGE_KEY_PREFIX,
+ max_read, &vals, &more);
if (r < 0) {
CLS_ERR("error reading mirror image directory by name: %s",
cpp_strerror(r).c_str());
}
int max_read = RBD_MAX_KEYS_READ;
- int r = max_read;
+ bool more = true;
map<string, string> groups;
string last_read = dir_key_for_name(start_after);
- while (r == max_read && groups.size() < max_return) {
+ while (more && groups.size() < max_return) {
map<string, bufferlist> vals;
CLS_LOG(20, "last_read = '%s'", last_read.c_str());
- r = cls_cxx_map_get_vals(hctx, last_read, RBD_DIR_NAME_KEY_PREFIX,
- max_read, &vals);
+ int r = cls_cxx_map_get_vals(hctx, last_read, RBD_DIR_NAME_KEY_PREFIX,
+ max_read, &vals, &more);
if (r < 0) {
CLS_ERR("error reading directory by name: %s", cpp_strerror(r).c_str());
return r;
std::map<string, bufferlist> vals;
string last_read = start_after.image_key();
std::vector<cls::rbd::GroupImageStatus> res;
- int keys_read;
+ bool more;
do {
- keys_read = cls_cxx_map_get_vals(hctx, last_read,cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX,
- max_read, &vals);
- if (keys_read < 0)
- return keys_read;
+ int r = cls_cxx_map_get_vals(hctx, last_read,cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX,
+ max_read, &vals, &more);
+ if (r < 0)
+ return r;
for (map<string, bufferlist>::iterator it = vals.begin();
it != vals.end() && res.size() < max_return; ++it) {
last_read = res.rbegin()->spec.image_key();
}
- } while ((keys_read == RBD_MAX_KEYS_READ) && (res.size() < max_return));
+ } while (more && (res.size() < max_return));
::encode(res, *out);
return 0;
* Returns the list of trash spec entries registered in the rbd_trash
* object.
*
+ * Input:
+ * @param start_after which name to begin listing after
+ * (use the empty string to start at the beginning)
+ * @param max_return the maximum number of names to list
+ *
* Output:
* @param data the map between image id and trash spec info
*
*/
int trash_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
{
+ string start_after;
+ uint64_t max_return;
+
+ try {
+ bufferlist::iterator iter = in->begin();
+ ::decode(start_after, iter);
+ ::decode(max_return, iter);
+ } catch (const buffer::error &err) {
+ return -EINVAL;
+ }
+
map<string, cls::rbd::TrashImageSpec> data;
- string last_read = trash::image_key("");
- int max_read = RBD_MAX_KEYS_READ;
+ string last_read = trash::image_key(start_after);
+ bool more = true;
CLS_LOG(20, "trash_get_images");
-
- do {
+ while (data.size() < max_return) {
map<string, bufferlist> raw_data;
+ int max_read = std::min<int32_t>(RBD_MAX_KEYS_READ,
+ max_return - data.size());
int r = cls_cxx_map_get_vals(hctx, last_read, trash::IMAGE_KEY_PREFIX,
- max_read, &raw_data);
+ max_read, &raw_data, &more);
if (r < 0) {
- CLS_ERR("failed to read the vals off of disk: %s", cpp_strerror(r).c_str());
+ CLS_ERR("failed to read the vals off of disk: %s",
+ cpp_strerror(r).c_str());
return r;
}
if (raw_data.empty()) {
::decode(data[trash::image_id_from_key(it->first)], it->second);
}
- if (r < max_read) {
+ if (!more) {
break;
}
last_read = raw_data.rbegin()->first;
- } while (max_read);
+ }
::encode(data, *out);
-
return 0;
}