static const string RBD_GROUP_SNAP_KEY_PREFIX = "snapshot_";
static const string RBD_GROUP_SNAP_ORDER_KEY_PREFIX = "snap_order_";
+static const string RBD_GROUP_SNAP_MAX_ORDER_KEY = "snap_max_order";
std::string snap_key(const std::string &snap_id) {
ostringstream oss;
return -EEXIST;
}
- std::string last_read = group::snap_order_key("");
- bool more;
uint64_t max_order = 0;
- std::map<string, bufferlist> vals;
- do {
- int r = cls_cxx_map_get_vals(hctx, last_read,
- group::RBD_GROUP_SNAP_ORDER_KEY_PREFIX,
- RBD_MAX_KEYS_READ, &vals, &more);
- if (r < 0) {
- return r;
- }
- for (auto &[key, bl] : vals) {
- auto iter = bl.cbegin();
- uint64_t order;
- try {
- decode(order, iter);
- } catch (const ceph::buffer::error &err) {
- CLS_ERR("error decoding snapshot order: %s", key.c_str());
- return -EIO;
- }
- max_order = std::max(max_order, order);
- }
- if (!vals.empty()) {
- last_read = vals.rbegin()->first;
- } else {
- ceph_assert(!more);
- }
- } while (more);
+
+ r = read_key(hctx, group::RBD_GROUP_SNAP_MAX_ORDER_KEY, &max_order);
+ if (r < 0 && r != -ENOENT) {
+ return r;
+ }
bufferlist bl;
encode(++max_order, bl);
+ r = cls_cxx_map_set_val(hctx, group::RBD_GROUP_SNAP_MAX_ORDER_KEY, &bl);
+ if (r < 0) {
+ CLS_ERR("error setting key: %s : %s",
+ group::RBD_GROUP_SNAP_MAX_ORDER_KEY.c_str(),
+ cpp_strerror(r).c_str());
+ return r;
+ }
r = cls_cxx_map_set_val(hctx, order_key, &bl);
if (r < 0) {
CLS_ERR("error setting key: %s : %s", order_key.c_str(),
set<string> keys;
ASSERT_EQ(0, ioctx.omap_get_keys(group_id, "", 10, &keys));
+ ASSERT_EQ(3U, keys.size());
auto it = keys.begin();
- ASSERT_EQ(2U, keys.size());
-
+ ASSERT_EQ("snap_max_order", *it++);
ASSERT_EQ("snap_order_" + snap.id, *it++);
ASSERT_EQ("snapshot_" + snap.id, *it);
}
set<string> keys;
ASSERT_EQ(0, ioctx.omap_get_keys(group_id, "", 10, &keys));
+ ASSERT_EQ(3U, keys.size());
auto it = keys.begin();
- ASSERT_EQ(2U, keys.size());
-
+ ASSERT_EQ("snap_max_order", *it++);
ASSERT_EQ("snap_order_" + snap.id, *it++);
ASSERT_EQ("snapshot_" + snap.id, *it);
ASSERT_EQ(0, ioctx.omap_get_keys(group_id, "", 10, &keys));
- ASSERT_EQ(0U, keys.size());
+ ASSERT_EQ(1U, keys.size());
+ ASSERT_EQ("snap_max_order", *keys.begin());
}
TEST_F(TestClsRbd, group_snap_remove_without_order) {
ASSERT_EQ(0, ioctx.omap_rm_keys(group_id, keys));
ASSERT_EQ(0, ioctx.omap_get_keys(group_id, "", 10, &keys));
- ASSERT_EQ(1U, keys.size());
+ ASSERT_EQ(2U, keys.size());
auto it = keys.begin();
+ ASSERT_EQ("snap_max_order", *it++);
ASSERT_EQ("snapshot_" + snap.id, *it);
// Remove the snapshot
ASSERT_EQ(0, group_snap_remove(&ioctx, group_id, snap_id));
+
+ ASSERT_EQ(0, ioctx.omap_get_keys(group_id, "", 10, &keys));
+ ASSERT_EQ(1U, keys.size());
+
+ ASSERT_EQ("snap_max_order", *keys.begin());
}
TEST_F(TestClsRbd, group_snap_get_by_id) {