]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: break composite cls rbd helpers into individual helpers
authorJason Dillaman <dillaman@redhat.com>
Fri, 27 Jul 2018 03:11:22 +0000 (23:11 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 19 Sep 2018 12:04:12 +0000 (08:04 -0400)
With the forthcoming need to use new methods to retrieve a clone's parent,
use per-method helpers to invoke the correct method within the image
refresh state machine.

Also used this time to merge newer cls rbd methods that should be supported
by all non-EOLed OSDs.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/cls/rbd/cls_rbd_client.cc
src/cls/rbd/cls_rbd_client.h
src/librbd/api/Mirror.cc
src/librbd/image/DetachChildRequest.cc
src/librbd/image/OpenRequest.cc
src/librbd/image/RefreshRequest.cc
src/librbd/image/RefreshRequest.h
src/librbd/operation/SnapshotRemoveRequest.cc
src/test/cls_rbd/CMakeLists.txt
src/test/cls_rbd/test_cls_rbd.cc
src/test/librbd/image/test_mock_RefreshRequest.cc

index 98221d0fa192d84e315d8d6c21fe388c9dedacea..0df92665591f7746f5e9a7dcf5179250f356ffb8 100644 (file)
 namespace librbd {
 namespace cls_client {
 
-void get_initial_metadata_start(librados::ObjectReadOperation *op) {
-  bufferlist bl, empty_bl, features_bl;
-  snapid_t snap = CEPH_NOSNAP;
-  encode(snap, bl);
-  op->exec("rbd", "get_size", bl);
-  op->exec("rbd", "get_object_prefix", empty_bl);
-
-  encode(snap, features_bl);
-  encode(true, features_bl);
-  op->exec("rbd", "get_features", features_bl);
-}
-
-int get_initial_metadata_finish(bufferlist::const_iterator *it,
-                                std::string *object_prefix,
-                                uint8_t *order,
-                                uint64_t *features) {
-  try {
-    uint64_t size;
-    uint64_t incompatible_features;
-    // get_size
-    decode(*order, *it);
-    decode(size, *it);
-    // get_object_prefix
-    decode(*object_prefix, *it);
-    // get_features
-    decode(*features, *it);
-    decode(incompatible_features, *it);
-  } catch (const buffer::error &err) {
-    return -EBADMSG;
-  }
-  return 0;
-
-}
-
-int get_initial_metadata(librados::IoCtx *ioctx, const std::string &oid,
-                         std::string *object_prefix, uint8_t *order, uint64_t *features)
-{
-  librados::ObjectReadOperation op;
-  get_initial_metadata_start(&op);
-
-  bufferlist out_bl;
-  int r = ioctx->operate(oid, &op, &out_bl);
-  if (r < 0) {
-    return r;
-  }
-
-  auto it = out_bl.cbegin();
-  return get_initial_metadata_finish(&it, object_prefix, order, features);
-}
-
-void get_mutable_metadata_start(librados::ObjectReadOperation *op,
-                                bool read_only) {
-  snapid_t snap = CEPH_NOSNAP;
-  bufferlist size_bl;
-  encode(snap, size_bl);
-  op->exec("rbd", "get_size", size_bl);
-
-  bufferlist features_bl;
-  encode(snap, features_bl);
-  encode(read_only, features_bl);
-  op->exec("rbd", "get_features", features_bl);
-
-  bufferlist empty_bl;
-  op->exec("rbd", "get_snapcontext", empty_bl);
-
-  get_parent_start(op, snap);
-
-  rados::cls::lock::get_lock_info_start(op, RBD_LOCK_NAME);
-}
-
-int get_mutable_metadata_finish(bufferlist::const_iterator *it,
-                                uint64_t *size, uint64_t *features,
-                                uint64_t *incompatible_features,
-                                std::map<rados::cls::lock::locker_id_t,
-                                         rados::cls::lock::locker_info_t> *lockers,
-                                bool *exclusive_lock, std::string *lock_tag,
-                                ::SnapContext *snapc, ParentInfo *parent) {
-  ceph_assert(size);
-  ceph_assert(features);
-  ceph_assert(incompatible_features);
-  ceph_assert(lockers);
-  ceph_assert(exclusive_lock);
-  ceph_assert(snapc);
-  ceph_assert(parent);
-
-  try {
-    uint8_t order;
-    // get_size
-    decode(order, *it);
-    decode(*size, *it);
-    // get_features
-    decode(*features, *it);
-    decode(*incompatible_features, *it);
-    // get_snapcontext
-    decode(*snapc, *it);
-    // get_parent
-    int r = get_parent_finish(it, &parent->spec, &parent->overlap);
-    if (r < 0) {
-      return r;
-    }
-
-    // get_lock_info
-    ClsLockType lock_type = LOCK_NONE;
-    r = rados::cls::lock::get_lock_info_finish(it, lockers, &lock_type,
-                 lock_tag);
-    if (r == 0) {
-      *exclusive_lock = (lock_type == LOCK_EXCLUSIVE);
-    }
-  } catch (const buffer::error &err) {
-    return -EBADMSG;
-  }
-  return 0;
-}
-
-int get_mutable_metadata(librados::IoCtx *ioctx, const std::string &oid,
-                         bool read_only, uint64_t *size, uint64_t *features,
-                         uint64_t *incompatible_features,
-                         map<rados::cls::lock::locker_id_t,
-                             rados::cls::lock::locker_info_t> *lockers,
-                                     bool *exclusive_lock,
-                         string *lock_tag,
-                         ::SnapContext *snapc,
-                         ParentInfo *parent)
-{
-  librados::ObjectReadOperation op;
-  get_mutable_metadata_start(&op, read_only);
-
-  bufferlist out_bl;
-  int r = ioctx->operate(oid, &op, &out_bl);
-  if (r < 0) {
-    return r;
-  }
-
-  auto it = out_bl.cbegin();
-  return get_mutable_metadata_finish(&it, size, features,
-                                     incompatible_features, lockers,
-                                     exclusive_lock, lock_tag, snapc,
-                                     parent);
-}
-
 void create_image(librados::ObjectWriteOperation *op, uint64_t size,
                   uint8_t order, uint64_t features,
                   const std::string &object_prefix, int64_t data_pool_id)
@@ -177,19 +37,20 @@ int create_image(librados::IoCtx *ioctx, const std::string &oid,
   return ioctx->operate(oid, &op);
 }
 
-int get_features(librados::IoCtx *ioctx, const std::string &oid,
-               snapid_t snap_id, uint64_t *features)
+void get_features_start(librados::ObjectReadOperation *op, bool read_only)
 {
-  bufferlist inbl, outbl;
-  encode(snap_id, inbl);
-
-  int r = ioctx->exec(oid, "rbd", "get_features", inbl, outbl);
-  if (r < 0)
-    return r;
+  bufferlist bl;
+  encode(static_cast<uint64_t>(CEPH_NOSNAP), bl);
+  encode(read_only, bl);
+  op->exec("rbd", "get_features", bl);
+}
 
+int get_features_finish(bufferlist::const_iterator *it, uint64_t *features,
+                        uint64_t *incompatible_features)
+{
   try {
-    auto iter = outbl.cbegin();
-    decode(*features, iter);
+    decode(*features, *it);
+    decode(*incompatible_features, *it);
   } catch (const buffer::error &err) {
     return -EBADMSG;
   }
@@ -197,6 +58,23 @@ int get_features(librados::IoCtx *ioctx, const std::string &oid,
   return 0;
 }
 
+int get_features(librados::IoCtx *ioctx, const std::string &oid,
+                 bool read_only, uint64_t *features,
+                 uint64_t *incompatible_features)
+{
+  librados::ObjectReadOperation op;
+  get_features_start(&op, read_only);
+
+  bufferlist out_bl;
+  int r = ioctx->operate(oid, &op, &out_bl);
+  if (r < 0) {
+    return r;
+  }
+
+  auto it = out_bl.cbegin();
+  return get_features_finish(&it, features, incompatible_features);
+}
+
 void set_features(librados::ObjectWriteOperation *op, uint64_t features,
                   uint64_t mask)
 {
@@ -216,24 +94,39 @@ int set_features(librados::IoCtx *ioctx, const std::string &oid,
   return ioctx->operate(oid, &op);
 }
 
-int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid,
-                      std::string *object_prefix)
+void get_object_prefix_start(librados::ObjectReadOperation *op)
 {
-  bufferlist inbl, outbl;
-  int r = ioctx->exec(oid, "rbd", "get_object_prefix", inbl, outbl);
-  if (r < 0)
-    return r;
+  bufferlist bl;
+  op->exec("rbd", "get_object_prefix", bl);
+}
 
+int get_object_prefix_finish(bufferlist::const_iterator *it,
+                             std::string *object_prefix)
+{
   try {
-    auto iter = outbl.cbegin();
-    decode(*object_prefix, iter);
+    decode(*object_prefix, *it);
   } catch (const buffer::error &err) {
     return -EBADMSG;
   }
-
   return 0;
 }
 
+int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid,
+                      std::string *object_prefix)
+{
+  librados::ObjectReadOperation op;
+  get_object_prefix_start(&op);
+
+  bufferlist out_bl;
+  int r = ioctx->operate(oid, &op, &out_bl);
+  if (r < 0) {
+    return r;
+  }
+
+  auto it = out_bl.cbegin();
+  return get_object_prefix_finish(&it, object_prefix);
+}
+
 void get_data_pool_start(librados::ObjectReadOperation *op) {
   bufferlist bl;
   op->exec("rbd", "get_data_pool", bl);
@@ -263,27 +156,41 @@ int get_data_pool(librados::IoCtx *ioctx, const std::string &oid,
   return get_data_pool_finish(&it, data_pool_id);
 }
 
-int get_size(librados::IoCtx *ioctx, const std::string &oid,
-             snapid_t snap_id, uint64_t *size, uint8_t *order)
+void get_size_start(librados::ObjectReadOperation *op, snapid_t snap_id)
 {
-  bufferlist inbl, outbl;
-  encode(snap_id, inbl);
-
-  int r = ioctx->exec(oid, "rbd", "get_size", inbl, outbl);
-  if (r < 0)
-    return r;
+  bufferlist bl;
+  encode(snap_id, bl);
+  op->exec("rbd", "get_size", bl);
+}
 
+int get_size_finish(bufferlist::const_iterator *it, uint64_t *size,
+                    uint8_t *order)
+{
   try {
-    auto iter = outbl.cbegin();
-    decode(*order, iter);
-    decode(*size, iter);
+    decode(*order, *it);
+    decode(*size, *it);
   } catch (const buffer::error &err) {
     return -EBADMSG;
   }
-
   return 0;
 }
 
+int get_size(librados::IoCtx *ioctx, const std::string &oid,
+             snapid_t snap_id, uint64_t *size, uint8_t *order)
+{
+  librados::ObjectReadOperation op;
+  get_size_start(&op, snap_id);
+
+  bufferlist out_bl;
+  int r = ioctx->operate(oid, &op, &out_bl);
+  if (r < 0) {
+    return r;
+  }
+
+  auto it = out_bl.cbegin();
+  return get_size_finish(&it, size, order);
+}
+
 int set_size(librados::IoCtx *ioctx, const std::string &oid,
              uint64_t size)
 {
@@ -356,29 +263,15 @@ void set_parent(librados::ObjectWriteOperation *op,
   op->exec("rbd", "set_parent", in_bl);
 }
 
-void get_flags_start(librados::ObjectReadOperation *op,
-                     const std::vector<snapid_t> &snap_ids) {
+void get_flags_start(librados::ObjectReadOperation *op, snapid_t snap_id) {
   bufferlist in_bl;
-  encode(static_cast<snapid_t>(CEPH_NOSNAP), in_bl);
-
+  encode(static_cast<snapid_t>(snap_id), in_bl);
   op->exec("rbd", "get_flags", in_bl);
-  for (size_t i = 0; i < snap_ids.size(); ++i) {
-    bufferlist snap_bl;
-    encode(snap_ids[i], snap_bl);
-    op->exec("rbd", "get_flags", snap_bl);
-  }
-
 }
 
-int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags,
-                     const std::vector<snapid_t> &snap_ids,
-                     std::vector<uint64_t> *snap_flags) {
-  snap_flags->resize(snap_ids.size());
+int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags) {
   try {
     decode(*flags, *it);
-    for (size_t i = 0; i < snap_flags->size(); ++i) {
-      decode((*snap_flags)[i], *it);
-    }
   } catch (const buffer::error &err) {
     return -EBADMSG;
   }
@@ -386,11 +279,10 @@ int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags,
 }
 
 int get_flags(librados::IoCtx *ioctx, const std::string &oid,
-              uint64_t *flags, const std::vector<snapid_t> &snap_ids,
-              vector<uint64_t> *snap_flags)
+              snapid_t snap_id, uint64_t *flags)
 {
   librados::ObjectReadOperation op;
-  get_flags_start(&op, snap_ids);
+  get_flags_start(&op, snap_id);
 
   bufferlist out_bl;
   int r = ioctx->operate(oid, &op, &out_bl);
@@ -399,7 +291,7 @@ int get_flags(librados::IoCtx *ioctx, const std::string &oid,
   }
 
   auto it = out_bl.cbegin();
-  return get_flags_finish(&it, flags, snap_ids, snap_flags);
+  return get_flags_finish(&it, flags);
 }
 
 void set_flags(librados::ObjectWriteOperation *op, snapid_t snap_id,
@@ -549,16 +441,15 @@ int get_children(librados::IoCtx *ioctx, const std::string &oid,
   return get_children_finish(&it, &children);
 }
 
-void snapshot_info_get_start(librados::ObjectReadOperation *op,
-                             snapid_t snap_id)
+void snapshot_get_start(librados::ObjectReadOperation *op, snapid_t snap_id)
 {
   bufferlist bl;
   encode(snap_id, bl);
   op->exec("rbd", "snapshot_get", bl);
 }
 
-int snapshot_info_get_finish(bufferlist::const_iterator* it,
-                             cls::rbd::SnapshotInfo* snap_info)
+int snapshot_get_finish(bufferlist::const_iterator* it,
+                        cls::rbd::SnapshotInfo* snap_info)
 {
   try {
     decode(*snap_info, *it);
@@ -568,60 +459,11 @@ int snapshot_info_get_finish(bufferlist::const_iterator* it,
   return 0;
 }
 
-void snapshot_get_start(librados::ObjectReadOperation *op,
-                        const std::vector<snapid_t> &ids)
-{
-  for (auto snap_id : ids) {
-    snapshot_info_get_start(op, snap_id);
-    get_parent_start(op, snap_id);
-    get_protection_status_start(op, snap_id);
-  }
-}
-
-int snapshot_get_finish(bufferlist::const_iterator *it,
-                        const std::vector<snapid_t> &ids,
-                        std::vector<cls::rbd::SnapshotInfo>* snaps,
-                        std::vector<ParentInfo> *parents,
-                        std::vector<uint8_t> *protection_statuses)
-{
-  snaps->resize(ids.size());
-  parents->resize(ids.size());
-  protection_statuses->resize(ids.size());
-  try {
-    for (size_t i = 0; i < snaps->size(); ++i) {
-      // snapshot_get
-      int r = snapshot_info_get_finish(it, &(*snaps)[i]);
-      if (r < 0) {
-        return r;
-      }
-
-      // get_parent
-      r = get_parent_finish(it, &(*parents)[i].spec,
-                            &(*parents)[i].overlap);
-      if (r < 0) {
-        return r;
-      }
-
-      // get_protection_status
-      r = get_protection_status_finish(it, &(*protection_statuses)[i]);
-      if (r < 0) {
-        return r;
-      }
-    }
-  } catch (const buffer::error &err) {
-    return -EBADMSG;
-  }
-  return 0;
-}
-
-int snapshot_get(librados::IoCtx* ioctx, const std::string& oid,
-                 const std::vector<snapid_t>& ids,
-                 std::vector<cls::rbd::SnapshotInfo>* snaps,
-                 std::vector<ParentInfo> *parents,
-                 std::vector<uint8_t> *protection_statuses)
+int snapshot_get(librados::IoCtx *ioctx, const std::string &oid,
+                 snapid_t snap_id, cls::rbd::SnapshotInfo* snap_info)
 {
   librados::ObjectReadOperation op;
-  snapshot_get_start(&op, ids);
+  snapshot_get_start(&op, snap_id);
 
   bufferlist out_bl;
   int r = ioctx->operate(oid, &op, &out_bl);
@@ -630,7 +472,7 @@ int snapshot_get(librados::IoCtx* ioctx, const std::string& oid,
   }
 
   auto it = out_bl.cbegin();
-  return snapshot_get_finish(&it, ids, snaps, parents, protection_statuses);
+  return snapshot_get_finish(&it, snap_info);
 }
 
 void snapshot_add(librados::ObjectWriteOperation *op, snapid_t snap_id,
@@ -705,67 +547,30 @@ int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid,
   return get_snapcontext_finish(&bl_it, snapc);
 }
 
-void snapshot_list_start(librados::ObjectReadOperation *op,
-                         const std::vector<snapid_t> &ids) {
-  for (auto snap_id : ids) {
-    bufferlist bl1, bl2;
-    encode(snap_id, bl1);
-    op->exec("rbd", "get_snapshot_name", bl1);
-    encode(snap_id, bl2);
-    op->exec("rbd", "get_size", bl2);
-    get_parent_start(op, snap_id);
-    get_protection_status_start(op, snap_id);
-  }
+void get_snapshot_name_start(librados::ObjectReadOperation *op,
+                             snapid_t snap_id)
+{
+  bufferlist bl;
+  encode(snap_id, bl);
+  op->exec("rbd", "get_snapshot_name", bl);
 }
 
-int snapshot_list_finish(bufferlist::const_iterator *it,
-                         const std::vector<snapid_t> &ids,
-                         std::vector<string> *names,
-                         std::vector<uint64_t> *sizes,
-                         std::vector<ParentInfo> *parents,
-                         std::vector<uint8_t> *protection_statuses)
+int get_snapshot_name_finish(bufferlist::const_iterator *it,
+                             std::string *name)
 {
-  names->resize(ids.size());
-  sizes->resize(ids.size());
-  parents->resize(ids.size());
-  protection_statuses->resize(ids.size());
   try {
-    for (size_t i = 0; i < names->size(); ++i) {
-      uint8_t order;
-      // get_snapshot_name
-      decode((*names)[i], *it);
-      // get_size
-      decode(order, *it);
-      decode((*sizes)[i], *it);
-
-      // get_parent
-      int r = get_parent_finish(it, &(*parents)[i].spec,
-                                &(*parents)[i].overlap);
-      if (r < 0) {
-        return r;
-      }
-
-      // get_protection_status
-      r = get_protection_status_finish(it, &(*protection_statuses)[i]);
-      if (r < 0) {
-        return r;
-      }
-    }
+    decode(*name, *it);
   } catch (const buffer::error &err) {
     return -EBADMSG;
   }
   return 0;
 }
 
-int snapshot_list(librados::IoCtx *ioctx, const std::string &oid,
-                  const std::vector<snapid_t> &ids,
-                  std::vector<string> *names,
-                  std::vector<uint64_t> *sizes,
-                  std::vector<ParentInfo> *parents,
-                  std::vector<uint8_t> *protection_statuses)
+int get_snapshot_name(librados::IoCtx *ioctx, const std::string &oid,
+                      snapid_t snap_id, std::string *name)
 {
   librados::ObjectReadOperation op;
-  snapshot_list_start(&op, ids);
+  get_snapshot_name_start(&op, snap_id);
 
   bufferlist out_bl;
   int r = ioctx->operate(oid, &op, &out_bl);
@@ -774,43 +579,33 @@ int snapshot_list(librados::IoCtx *ioctx, const std::string &oid,
   }
 
   auto it = out_bl.cbegin();
-  return snapshot_list_finish(&it, ids, names, sizes, parents,
-                              protection_statuses);
+  return get_snapshot_name_finish(&it, name);
 }
 
-void snapshot_timestamp_list_start(librados::ObjectReadOperation *op,
-                                   const std::vector<snapid_t> &ids)
+void get_snapshot_timestamp_start(librados::ObjectReadOperation *op,
+                                  snapid_t snap_id)
 {
-  for (auto snap_id : ids) {
-    bufferlist bl;
-    encode(snap_id, bl);
-    op->exec("rbd", "get_snapshot_timestamp", bl);
-  }
+  bufferlist bl;
+  encode(snap_id, bl);
+  op->exec("rbd", "get_snapshot_timestamp", bl);
 }
 
-int snapshot_timestamp_list_finish(bufferlist::const_iterator *it,
-                                   const std::vector<snapid_t> &ids,
-                                   std::vector<utime_t> *timestamps)
+int get_snapshot_timestamp_finish(bufferlist::const_iterator *it,
+                                  utime_t *timestamp)
 {
-  timestamps->resize(ids.size());
   try {
-    for (size_t i = 0; i < timestamps->size(); ++i) {
-      utime_t t;
-      decode(t, *it);
-      (*timestamps)[i] = t;
-    }
+    decode(*timestamp, *it);
   } catch (const buffer::error &err) {
     return -EBADMSG;
   }
   return 0;
 }
 
-int snapshot_timestamp_list(librados::IoCtx *ioctx, const std::string &oid,
-                            const std::vector<snapid_t> &ids,
-                            std::vector<utime_t> *timestamps)
+int get_snapshot_timestamp(librados::IoCtx *ioctx, const std::string &oid,
+                           snapid_t snap_id, utime_t *timestamp)
 {
   librados::ObjectReadOperation op;
-  snapshot_timestamp_list_start(&op, ids);
+  get_snapshot_timestamp_start(&op, snap_id);
 
   bufferlist out_bl;
   int r = ioctx->operate(oid, &op, &out_bl);
@@ -819,7 +614,7 @@ int snapshot_timestamp_list(librados::IoCtx *ioctx, const std::string &oid,
   }
 
   auto it = out_bl.cbegin();
-  return snapshot_timestamp_list_finish(&it, ids, timestamps);
+  return get_snapshot_timestamp_finish(&it, timestamp);
 }
 
 void old_snapshot_add(librados::ObjectWriteOperation *op,
index b082e7c1c26562d41a3d45c0c58da290e9577c57..e72d533d3613e1959e2625c77b2ef41a978bc135 100644 (file)
@@ -22,34 +22,6 @@ namespace librados {
 namespace librbd {
 namespace cls_client {
 
-// high-level interface to the header
-void get_initial_metadata_start(librados::ObjectReadOperation *op);
-int get_initial_metadata_finish(bufferlist::const_iterator *it,
-                                std::string *object_prefix,
-                                uint8_t *order,
-                                uint64_t *features);
-int get_initial_metadata(librados::IoCtx *ioctx, const std::string &oid,
-                         std::string *object_prefix, uint8_t *order, uint64_t *features);
-
-void get_mutable_metadata_start(librados::ObjectReadOperation *op,
-                                bool read_only);
-int get_mutable_metadata_finish(bufferlist::const_iterator *it,
-                                uint64_t *size, uint64_t *features,
-                                uint64_t *incompatible_features,
-                                std::map<rados::cls::lock::locker_id_t,
-                                         rados::cls::lock::locker_info_t> *lockers,
-                                bool *exclusive_lock, std::string *lock_tag,
-              ::SnapContext *snapc, ParentInfo *parent);
-int get_mutable_metadata(librados::IoCtx *ioctx, const std::string &oid,
-                         bool read_only, uint64_t *size, uint64_t *features,
-                         uint64_t *incompatible_features,
-                         map<rados::cls::lock::locker_id_t,
-                             rados::cls::lock::locker_info_t> *lockers,
-                         bool *exclusive_lock,
-                         std::string *lock_tag,
-                         ::SnapContext *snapc,
-                         ParentInfo *parent);
-
 // low-level interface (mainly for testing)
 void create_image(librados::ObjectWriteOperation *op, uint64_t size,
                   uint8_t order, uint64_t features,
@@ -57,18 +29,32 @@ void create_image(librados::ObjectWriteOperation *op, uint64_t size,
 int create_image(librados::IoCtx *ioctx, const std::string &oid,
                  uint64_t size, uint8_t order, uint64_t features,
                  const std::string &object_prefix, int64_t data_pool_id);
+
+void get_features_start(librados::ObjectReadOperation *op, bool read_only);
+int get_features_finish(bufferlist::const_iterator *it, uint64_t *features,
+                        uint64_t *incompatible_features);
 int get_features(librados::IoCtx *ioctx, const std::string &oid,
-                 snapid_t snap_id, uint64_t *features);
+                 bool read_only, uint64_t *features,
+                 uint64_t *incompatible_features);
 void set_features(librados::ObjectWriteOperation *op, uint64_t features,
                   uint64_t mask);
 int set_features(librados::IoCtx *ioctx, const std::string &oid,
                  uint64_t features, uint64_t mask);
+
+void get_object_prefix_start(librados::ObjectReadOperation *op);
+int get_object_prefix_finish(bufferlist::const_iterator *it,
+                             std::string *object_prefix);
 int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid,
                       std::string *object_prefix);
+
 void get_data_pool_start(librados::ObjectReadOperation *op);
 int get_data_pool_finish(bufferlist::const_iterator *it, int64_t *data_pool_id);
 int get_data_pool(librados::IoCtx *ioctx, const std::string &oid,
                   int64_t *data_pool_id);
+
+void get_size_start(librados::ObjectReadOperation *op, snapid_t snap_id);
+int get_size_finish(bufferlist::const_iterator *it, uint64_t *size,
+                    uint8_t *order);
 int get_size(librados::IoCtx *ioctx, const std::string &oid,
              snapid_t snap_id, uint64_t *size, uint8_t *order);
 int set_size(librados::IoCtx *ioctx, const std::string &oid,
@@ -86,16 +72,15 @@ int set_parent(librados::IoCtx *ioctx, const std::string &oid,
                const ParentSpec &pspec, uint64_t parent_overlap);
 void set_parent(librados::ObjectWriteOperation *op,
                 const ParentSpec &pspec, uint64_t parent_overlap);
-void get_flags_start(librados::ObjectReadOperation *op,
-                     const std::vector<snapid_t> &snap_ids);
-int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags,
-                     const std::vector<snapid_t> &snap_ids,
-                     std::vector<uint64_t> *snap_flags);
+
+void get_flags_start(librados::ObjectReadOperation *op, snapid_t snap_id);
+int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags);
 int get_flags(librados::IoCtx *ioctx, const std::string &oid,
-              uint64_t *flags, const std::vector<snapid_t> &snap_ids,
-              vector<uint64_t> *snap_flags);
+              snapid_t snap_id, uint64_t *flags);
+
 void set_flags(librados::ObjectWriteOperation *op, snapid_t snap_id,
                uint64_t flags, uint64_t mask);
+
 void op_features_get_start(librados::ObjectReadOperation *op);
 int op_features_get_finish(bufferlist::const_iterator *it, uint64_t *op_features);
 int op_features_get(librados::IoCtx *ioctx, const std::string &oid,
@@ -121,23 +106,12 @@ int get_children_finish(bufferlist::const_iterator *it,
 int get_children(librados::IoCtx *ioctx, const std::string &oid,
                  const ParentSpec &pspec, set<string>& children);
 
-void snapshot_info_get_start(librados::ObjectReadOperation* op,
-                             snapid_t snap_id);
-int snapshot_info_get_finish(bufferlist::const_iterator* it,
-                             cls::rbd::SnapshotInfo* snap_info);
-
-void snapshot_get_start(librados::ObjectReadOperation *op,
-                        const std::vector<snapid_t> &ids);
-int snapshot_get_finish(bufferlist::const_iterator *it,
-                        const std::vector<snapid_t> &ids,
-                        std::vector<cls::rbd::SnapshotInfo>* snaps,
-                        std::vector<ParentInfo> *parents,
-                        std::vector<uint8_t> *protection_statuses);
-int snapshot_get(librados::IoCtx* ioctx, const std::string& oid,
-                 const std::vector<snapid_t>& ids,
-                 std::vector<cls::rbd::SnapshotInfo>* snaps,
-                 std::vector<ParentInfo> *parents,
-                 std::vector<uint8_t> *protection_statuses);
+void snapshot_get_start(librados::ObjectReadOperation* op,
+                        snapid_t snap_id);
+int snapshot_get_finish(bufferlist::const_iterator* it,
+                        cls::rbd::SnapshotInfo* snap_info);
+int snapshot_get(librados::IoCtx *ioctx, const std::string &oid,
+                 snapid_t snap_id, cls::rbd::SnapshotInfo* snap_info);
 
 void snapshot_add(librados::ObjectWriteOperation *op, snapid_t snap_id,
                   const std::string &snap_name,
@@ -156,30 +130,20 @@ int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid,
                     ::SnapContext *snapc);
 
 /// NOTE: remove after Luminous is retired
-void snapshot_list_start(librados::ObjectReadOperation *op,
-                         const std::vector<snapid_t> &ids);
-int snapshot_list_finish(bufferlist::const_iterator *it,
-                         const std::vector<snapid_t> &ids,
-                         std::vector<string> *names,
-                         std::vector<uint64_t> *sizes,
-                         std::vector<ParentInfo> *parents,
-                         std::vector<uint8_t> *protection_statuses);
-int snapshot_list(librados::IoCtx *ioctx, const std::string &oid,
-                  const std::vector<snapid_t> &ids,
-                  std::vector<string> *names,
-                  std::vector<uint64_t> *sizes,
-                  std::vector<ParentInfo> *parents,
-                  std::vector<uint8_t> *protection_statuses);
+void get_snapshot_name_start(librados::ObjectReadOperation *op,
+                             snapid_t snap_id);
+int get_snapshot_name_finish(bufferlist::const_iterator *it,
+                             std::string *name);
+int get_snapshot_name(librados::IoCtx *ioctx, const std::string &oid,
+                      snapid_t snap_id, std::string *name);
 
 /// NOTE: remove after Luminous is retired
-void snapshot_timestamp_list_start(librados::ObjectReadOperation *op,
-                                   const std::vector<snapid_t> &ids);
-int snapshot_timestamp_list_finish(bufferlist::const_iterator *it,
-                                   const std::vector<snapid_t> &ids,
-                                   std::vector<utime_t> *timestamps);
-int snapshot_timestamp_list(librados::IoCtx *ioctx, const std::string &oid,
-                            const std::vector<snapid_t> &ids,
-                            std::vector<utime_t> *timestamps);
+void get_snapshot_timestamp_start(librados::ObjectReadOperation *op,
+                                  snapid_t snap_id);
+int get_snapshot_timestamp_finish(bufferlist::const_iterator *it,
+                                  utime_t *timestamp);
+int get_snapshot_timestamp(librados::IoCtx *ioctx, const std::string &oid,
+                           snapid_t snap_id, utime_t *timestamp);
 
 void get_all_features_start(librados::ObjectReadOperation *op);
 int get_all_features_finish(bufferlist::const_iterator *it,
@@ -202,6 +166,7 @@ int set_protection_status(librados::IoCtx *ioctx, const std::string &oid,
                           snapid_t snap_id, uint8_t protection_status);
 void set_protection_status(librados::ObjectWriteOperation *op,
                            snapid_t snap_id, uint8_t protection_status);
+
 int snapshot_get_limit(librados::IoCtx *ioctx, const std::string &oid,
                        uint64_t *limit);
 void snapshot_set_limit(librados::ObjectWriteOperation *op,
@@ -278,7 +243,6 @@ int children_list_finish(bufferlist::const_iterator *it,
 int children_list(librados::IoCtx *ioctx, const std::string &oid,
                   snapid_t snap_id,
                   cls::rbd::ChildImageSpecs *child_images);
-
 int migration_set(librados::IoCtx *ioctx, const std::string &oid,
                   const cls::rbd::MigrationSpec &migration_spec);
 void migration_set(librados::ObjectWriteOperation *op,
index 3a2dff18cf6129f62a2f743e7656d481827b9656..b9eac8313dbf55c1c327ae89a8f2e28a05b3d9bf 100644 (file)
@@ -585,9 +585,9 @@ int Mirror<I>::mode_set(librados::IoCtx& io_ctx,
 
     for (const auto& img_pair : images) {
       uint64_t features;
-      r = cls_client::get_features(&io_ctx,
-                                   util::header_name(img_pair.second),
-                                   CEPH_NOSNAP, &features);
+      uint64_t incompatible_features;
+      r = cls_client::get_features(&io_ctx, util::header_name(img_pair.second),
+                                   true, &features, &incompatible_features);
       if (r < 0) {
         lderr(cct) << "error getting features for image " << img_pair.first
                    << ": " << cpp_strerror(r) << dendl;
index 43922750f9236aa0e2bbfd1101cf820b03698e90..b91cc0d19d04b8bffa80714a7a8523f62ce96fa6 100644 (file)
@@ -103,7 +103,7 @@ void DetachChildRequest<I>::clone_v2_get_snapshot() {
   ldout(cct, 5) << dendl;
 
   librados::ObjectReadOperation op;
-  cls_client::snapshot_info_get_start(&op, m_parent_spec.snap_id);
+  cls_client::snapshot_get_start(&op, m_parent_spec.snap_id);
 
   m_out_bl.clear();
   auto aio_comp = create_rados_callback<
@@ -124,7 +124,7 @@ void DetachChildRequest<I>::handle_clone_v2_get_snapshot(int r) {
   if (r == 0) {
     cls::rbd::SnapshotInfo snap_info;
     auto it = m_out_bl.cbegin();
-    r = cls_client::snapshot_info_get_finish(&it, &snap_info);
+    r = cls_client::snapshot_get_finish(&it, &snap_info);
     if (r == 0) {
       m_parent_snap_namespace = snap_info.snapshot_namespace;
       m_parent_snap_name = snap_info.name;
index 113e5d622694e3129fddcc66cf6f78b3fbdff1fd..b18b512ad57f9c4f97540fa1a7bdadc2c2f01122 100644 (file)
@@ -255,7 +255,9 @@ void OpenRequest<I>::send_v2_get_initial_metadata() {
   m_image_ctx->header_oid = util::header_name(m_image_ctx->id);
 
   librados::ObjectReadOperation op;
-  cls_client::get_initial_metadata_start(&op);
+  cls_client::get_size_start(&op, CEPH_NOSNAP);
+  cls_client::get_object_prefix_start(&op);
+  cls_client::get_features_start(&op, true);
 
   using klass = OpenRequest<I>;
   librados::AioCompletion *comp = create_rados_callback<
@@ -271,11 +273,23 @@ Context *OpenRequest<I>::handle_v2_get_initial_metadata(int *result) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << __func__ << ": r=" << *result << dendl;
 
-  if (*result == 0) {
-    auto it = m_out_bl.cbegin();
-    *result = cls_client::get_initial_metadata_finish(
-      &it, &m_image_ctx->object_prefix, &m_image_ctx->order, &m_image_ctx->features);
+  auto it = m_out_bl.cbegin();
+  if (*result >= 0) {
+    uint64_t size;
+    *result = cls_client::get_size_finish(&it, &size, &m_image_ctx->order);
+  }
+
+  if (*result >= 0) {
+    *result = cls_client::get_object_prefix_finish(&it,
+                                                   &m_image_ctx->object_prefix);
   }
+
+  if (*result >= 0) {
+    uint64_t incompatible_features;
+    *result = cls_client::get_features_finish(&it, &m_image_ctx->features,
+                                              &incompatible_features);
+  }
+
   if (*result < 0) {
     lderr(cct) << "failed to retrieve initial metadata: "
                << cpp_strerror(*result) << dendl;
index a5289a6dc520a7434bc53b831a16ec9e3654116e..6c1218b94a92411c3f8a3af5450d8f5e2893dfef 100644 (file)
@@ -287,11 +287,7 @@ Context *RefreshRequest<I>::handle_v1_get_locks(int *result) {
   ldout(cct, 10) << this << " " << __func__ << ": "
                  << "r=" << *result << dendl;
 
-  // If EOPNOTSUPP, treat image as if there are no locks (we can't
-  // query them).
-  if (*result == -EOPNOTSUPP) {
-    *result = 0;
-  } else if (*result == 0) {
+  if (*result == 0) {
     auto it = m_out_bl.cbegin();
     ClsLockType lock_type;
     *result = rados::cls::lock::get_lock_info_finish(&it, &m_lockers,
@@ -344,7 +340,11 @@ void RefreshRequest<I>::send_v2_get_mutable_metadata() {
 
   bool read_only = m_image_ctx.read_only || snap_id != CEPH_NOSNAP;
   librados::ObjectReadOperation op;
-  cls_client::get_mutable_metadata_start(&op, read_only);
+  cls_client::get_size_start(&op, CEPH_NOSNAP);
+  cls_client::get_features_start(&op, read_only);
+  cls_client::get_flags_start(&op, CEPH_NOSNAP);
+  cls_client::get_snapcontext_start(&op);
+  rados::cls::lock::get_lock_info_start(&op, RBD_LOCK_NAME);
 
   using klass = RefreshRequest<I>;
   librados::AioCompletion *comp = create_rados_callback<
@@ -362,15 +362,34 @@ Context *RefreshRequest<I>::handle_v2_get_mutable_metadata(int *result) {
   ldout(cct, 10) << this << " " << __func__ << ": "
                  << "r=" << *result << dendl;
 
-  if (*result == 0) {
-    auto it = m_out_bl.cbegin();
-    *result = cls_client::get_mutable_metadata_finish(&it, &m_size, &m_features,
-                                                      &m_incompatible_features,
-                                                      &m_lockers,
-                                                      &m_exclusive_locked,
-                                                      &m_lock_tag, &m_snapc,
-                                                      &m_parent_md);
+  auto it = m_out_bl.cbegin();
+  if (*result >= 0) {
+    uint8_t order;
+    *result = cls_client::get_size_finish(&it, &m_size, &order);
+  }
+
+  if (*result >= 0) {
+    *result = cls_client::get_features_finish(&it, &m_features,
+                                              &m_incompatible_features);
+  }
+
+  if (*result >= 0) {
+    *result = cls_client::get_flags_finish(&it, &m_flags);
+  }
+
+  if (*result >= 0) {
+    *result = cls_client::get_snapcontext_finish(&it, &m_snapc);
+  }
+
+  if (*result >= 0) {
+    ClsLockType lock_type = LOCK_NONE;
+    *result = rados::cls::lock::get_lock_info_finish(&it, &m_lockers,
+                                                     &lock_type, &m_lock_tag);
+    if (*result == 0) {
+      m_exclusive_locked = (lock_type == LOCK_EXCLUSIVE);
+    }
   }
+
   if (*result < 0) {
     lderr(cct) << "failed to retrieve mutable metadata: "
                << cpp_strerror(*result) << dendl;
@@ -396,6 +415,45 @@ Context *RefreshRequest<I>::handle_v2_get_mutable_metadata(int *result) {
     m_incomplete_update = true;
   }
 
+  send_v2_get_parent();
+  return nullptr;
+}
+
+template <typename I>
+void RefreshRequest<I>::send_v2_get_parent() {
+  // NOTE: remove support when Mimic is EOLed
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << this << " " << __func__ << dendl;
+
+  librados::ObjectReadOperation op;
+  cls_client::get_parent_start(&op, CEPH_NOSNAP);
+
+  auto aio_comp = create_rados_callback<
+    RefreshRequest<I>, &RefreshRequest<I>::handle_v2_get_parent>(this);
+  m_out_bl.clear();
+  m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, aio_comp, &op,
+                                  &m_out_bl);
+  aio_comp->release();
+}
+
+template <typename I>
+Context *RefreshRequest<I>::handle_v2_get_parent(int *result) {
+  // NOTE: remove support when Mimic is EOLed
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl;
+
+  if (*result == 0) {
+    auto it = m_out_bl.cbegin();
+    *result = cls_client::get_parent_finish(&it, &m_parent_md.spec,
+                                            &m_parent_md.overlap);
+  }
+
+  if (*result < 0) {
+    lderr(cct) << "failed to retrieve parent: " << cpp_strerror(*result)
+               << dendl;
+    return m_on_finish;
+  }
+
   if ((m_features & RBD_FEATURE_MIGRATING) != 0) {
     ldout(cct, 1) << "migrating feature set" << dendl;
     send_get_migration_header();
@@ -435,9 +493,7 @@ Context *RefreshRequest<I>::handle_v2_get_metadata(int *result) {
     *result = cls_client::metadata_list_finish(&it, &metadata);
   }
 
-  if (*result == -EOPNOTSUPP || *result == -EIO) {
-    ldout(cct, 10) << "config metadata not supported by OSD" << dendl;
-  } else if (*result < 0) {
+  if (*result < 0) {
     lderr(cct) << "failed to retrieve metadata: " << cpp_strerror(*result)
                << dendl;
     return m_on_finish;
@@ -456,61 +512,6 @@ Context *RefreshRequest<I>::handle_v2_get_metadata(int *result) {
   bool thread_safe = m_image_ctx.image_watcher->is_unregistered();
   m_image_ctx.apply_metadata(m_metadata, thread_safe);
 
-  send_v2_get_flags();
-  return nullptr;
-}
-
-template <typename I>
-void RefreshRequest<I>::send_v2_get_flags() {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << this << " " << __func__ << dendl;
-
-  librados::ObjectReadOperation op;
-  cls_client::get_flags_start(&op, m_snapc.snaps);
-
-  using klass = RefreshRequest<I>;
-  librados::AioCompletion *comp = create_rados_callback<
-    klass, &klass::handle_v2_get_flags>(this);
-  m_out_bl.clear();
-  int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, comp, &op,
-                                         &m_out_bl);
-  ceph_assert(r == 0);
-  comp->release();
-}
-
-template <typename I>
-Context *RefreshRequest<I>::handle_v2_get_flags(int *result) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << this << " " << __func__ << ": "
-                 << "r=" << *result << dendl;
-
-  if (*result == 0) {
-    /// NOTE: remove support for snap paramter after Luminous is retired
-    auto it = m_out_bl.cbegin();
-    cls_client::get_flags_finish(&it, &m_flags, m_snapc.snaps, &m_snap_flags);
-  }
-  if (*result == -EOPNOTSUPP) {
-    // Older OSD doesn't support RBD flags, need to assume the worst
-    *result = 0;
-    ldout(cct, 10) << "OSD does not support RBD flags, disabling object map "
-                   << "optimizations" << dendl;
-    m_flags = RBD_FLAG_OBJECT_MAP_INVALID;
-    if ((m_features & RBD_FEATURE_FAST_DIFF) != 0) {
-      m_flags |= RBD_FLAG_FAST_DIFF_INVALID;
-    }
-
-    std::vector<uint64_t> default_flags(m_snapc.snaps.size(), m_flags);
-    m_snap_flags = std::move(default_flags);
-  } else if (*result == -ENOENT) {
-    ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl;
-    send_v2_get_mutable_metadata();
-    return nullptr;
-  } else if (*result < 0) {
-    lderr(cct) << "failed to retrieve flags: " << cpp_strerror(*result)
-               << dendl;
-    return m_on_finish;
-  }
-
   send_v2_get_op_features();
   return nullptr;
 }
@@ -586,11 +587,7 @@ Context *RefreshRequest<I>::handle_v2_get_group(int *result) {
     auto it = m_out_bl.cbegin();
     cls_client::image_group_get_finish(&it, &m_group_spec);
   }
-  if (*result == -EOPNOTSUPP) {
-    // Older OSD doesn't support RBD groups
-    *result = 0;
-    ldout(cct, 10) << "OSD does not support groups" << dendl;
-  } else if (*result < 0) {
+  if (*result < 0) {
     lderr(cct) << "failed to retrieve group: " << cpp_strerror(*result)
                << dendl;
     return m_on_finish;
@@ -602,10 +599,12 @@ Context *RefreshRequest<I>::handle_v2_get_group(int *result) {
 
 template <typename I>
 void RefreshRequest<I>::send_v2_get_snapshots() {
+  m_snap_infos.resize(m_snapc.snaps.size());
+  m_snap_flags.resize(m_snapc.snaps.size());
+  m_snap_parents.resize(m_snapc.snaps.size());
+  m_snap_protection.resize(m_snapc.snaps.size());
+
   if (m_snapc.snaps.empty()) {
-    m_snap_infos.clear();
-    m_snap_parents.clear();
-    m_snap_protection.clear();
     send_v2_refresh_parent();
     return;
   }
@@ -614,7 +613,19 @@ void RefreshRequest<I>::send_v2_get_snapshots() {
   ldout(cct, 10) << this << " " << __func__ << dendl;
 
   librados::ObjectReadOperation op;
-  cls_client::snapshot_get_start(&op, m_snapc.snaps);
+  for (auto snap_id : m_snapc.snaps) {
+    if (m_legacy_snapshot) {
+      /// NOTE: remove after Luminous is retired
+      cls_client::get_snapshot_name_start(&op, snap_id);
+      cls_client::get_size_start(&op, snap_id);
+      cls_client::get_snapshot_timestamp_start(&op, snap_id);
+    } else {
+      cls_client::snapshot_get_start(&op, snap_id);
+    }
+    cls_client::get_flags_start(&op, snap_id);
+    cls_client::get_parent_start(&op, snap_id);
+    cls_client::get_protection_status_start(&op, snap_id);
+  }
 
   using klass = RefreshRequest<I>;
   librados::AioCompletion *comp = create_rados_callback<
@@ -629,141 +640,76 @@ void RefreshRequest<I>::send_v2_get_snapshots() {
 template <typename I>
 Context *RefreshRequest<I>::handle_v2_get_snapshots(int *result) {
   CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << this << " " << __func__ << ": "
-                 << "r=" << *result << dendl;
+  ldout(cct, 10) << this << " " << __func__ << ": " << "r=" << *result << dendl;
 
-  if (*result == 0) {
-    auto it = m_out_bl.cbegin();
-    *result = cls_client::snapshot_get_finish(&it, m_snapc.snaps, &m_snap_infos,
-                                              &m_snap_parents,
-                                              &m_snap_protection);
-  }
-  if (*result == -ENOENT) {
-    ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl;
-    send_v2_get_mutable_metadata();
-    return nullptr;
-  } else if (*result == -EOPNOTSUPP) {
-    ldout(cct, 10) << "retrying using legacy snapshot methods" << dendl;
-    send_v2_get_snapshots_legacy();
-    return nullptr;
-  } else if (*result < 0) {
-    lderr(cct) << "failed to retrieve snapshots: " << cpp_strerror(*result)
-               << dendl;
-    return m_on_finish;
-  }
+  auto it = m_out_bl.cbegin();
+  for (size_t i = 0; i < m_snapc.snaps.size(); ++i) {
+    if (m_legacy_snapshot) {
+      /// NOTE: remove after Luminous is retired
+      std::string snap_name;
+      if (*result >= 0) {
+        *result = cls_client::get_snapshot_name_finish(&it, &snap_name);
+      }
 
-  send_v2_refresh_parent();
-  return nullptr;
-}
+      uint64_t snap_size;
+      if (*result >= 0) {
+        uint8_t order;
+        *result = cls_client::get_size_finish(&it, &snap_size, &order);
+      }
 
-template <typename I>
-void RefreshRequest<I>::send_v2_get_snapshots_legacy() {
-  /// NOTE: remove after Luminous is retired
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << this << " " << __func__ << dendl;
+      utime_t snap_timestamp;
+      if (*result >= 0) {
+        *result = cls_client::get_snapshot_timestamp_finish(&it,
+                                                            &snap_timestamp);
+      }
 
-  librados::ObjectReadOperation op;
-  cls_client::snapshot_list_start(&op, m_snapc.snaps);
+      if (*result >= 0) {
+        m_snap_infos[i] = {m_snapc.snaps[i],
+                           {cls::rbd::UserSnapshotNamespace{}},
+                           snap_name, snap_size, snap_timestamp, 0};
+      }
+    } else if (*result >= 0) {
+      *result = cls_client::snapshot_get_finish(&it, &m_snap_infos[i]);
+    }
 
-  using klass = RefreshRequest<I>;
-  librados::AioCompletion *comp = create_rados_callback<
-    klass, &klass::handle_v2_get_snapshots_legacy>(this);
-  m_out_bl.clear();
-  int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, comp, &op,
-                                         &m_out_bl);
-  ceph_assert(r == 0);
-  comp->release();
-}
+    if (*result >= 0) {
+      *result = cls_client::get_flags_finish(&it, &m_snap_flags[i]);
+    }
 
-template <typename I>
-Context *RefreshRequest<I>::handle_v2_get_snapshots_legacy(int *result) {
-  /// NOTE: remove after Luminous is retired
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << this << " " << __func__ << ": "
-                 << "r=" << *result << dendl;
+    if (*result >= 0) {
+      *result = cls_client::get_parent_finish(&it, &m_snap_parents[i].spec,
+                                              &m_snap_parents[i].overlap);
+    }
 
-  std::vector<std::string> snap_names;
-  std::vector<uint64_t> snap_sizes;
-  if (*result == 0) {
-    auto it = m_out_bl.cbegin();
-    *result = cls_client::snapshot_list_finish(&it, m_snapc.snaps,
-                                               &snap_names, &snap_sizes,
-                                               &m_snap_parents,
-                                               &m_snap_protection);
-  }
-  if (*result == -ENOENT) {
-    ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl;
-    send_v2_get_mutable_metadata();
-    return nullptr;
-  } else if (*result < 0) {
-    lderr(cct) << "failed to retrieve snapshots: " << cpp_strerror(*result)
-               << dendl;
-    return m_on_finish;
-  }
+    if (*result >= 0) {
+      *result = cls_client::get_protection_status_finish(
+        &it, &m_snap_protection[i]);
+    }
 
-  m_snap_infos.clear();
-  for (size_t i = 0; i < m_snapc.snaps.size(); ++i) {
-    m_snap_infos.push_back({m_snapc.snaps[i],
-                            {cls::rbd::UserSnapshotNamespace{}},
-                            snap_names[i], snap_sizes[i], {}, 0});
+    if (*result < 0) {
+      break;
+    }
   }
 
-  send_v2_get_snap_timestamps();
-  return nullptr;
-}
-
-template <typename I>
-void RefreshRequest<I>::send_v2_get_snap_timestamps() {
-  /// NOTE: remove after Luminous is retired
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << this << " " << __func__ << dendl;
-
-  librados::ObjectReadOperation op;
-  cls_client::snapshot_timestamp_list_start(&op, m_snapc.snaps);
-
-  using klass = RefreshRequest<I>;
-  librados::AioCompletion *comp = create_rados_callback<
-                 klass, &klass::handle_v2_get_snap_timestamps>(this);
-  m_out_bl.clear();
-  int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, comp, &op,
-                                 &m_out_bl);
-  ceph_assert(r == 0);
-  comp->release();
-}
-
-template <typename I>
-Context *RefreshRequest<I>::handle_v2_get_snap_timestamps(int *result) {
-  /// NOTE: remove after Luminous is retired
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << this << " " << __func__ << ": " << "r=" << *result << dendl;
-
-  std::vector<utime_t> snap_timestamps;
-  if (*result == 0) {
-    auto it = m_out_bl.cbegin();
-    *result = cls_client::snapshot_timestamp_list_finish(&it, m_snapc.snaps,
-                                                         &snap_timestamps);
-  }
   if (*result == -ENOENT) {
     ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl;
     send_v2_get_mutable_metadata();
     return nullptr;
-  } else if (*result == -EOPNOTSUPP) {
-    // Ignore it means no snap timestamps are available
+  } else if (!m_legacy_snapshot && *result == -EOPNOTSUPP) {
+    ldout(cct, 10) << "retrying using legacy snapshot methods" << dendl;
+    m_legacy_snapshot = true;
+    send_v2_get_snapshots();
+    return nullptr;
   } else if (*result < 0) {
-    lderr(cct) << "failed to retrieve snapshot timestamps: "
-               << cpp_strerror(*result) << dendl;
+    lderr(cct) << "failed to retrieve snapshots: " << cpp_strerror(*result)
+               << dendl;
     return m_on_finish;
-  } else {
-    for (size_t i = 0; i < m_snapc.snaps.size(); ++i) {
-      m_snap_infos[i].timestamp = snap_timestamps[i];
-    }
   }
 
   send_v2_refresh_parent();
   return nullptr;
 }
 
-
 template <typename I>
 void RefreshRequest<I>::send_v2_refresh_parent() {
   {
index 86d7ea61e28ae7f741f018184a2f5a074b8d3740..1d982425dbab196a44e70aa6bf7cafcb18c691bf 100644 (file)
@@ -58,7 +58,7 @@ private:
    *            V2_GET_METADATA                            <apply>
    *                |                                         |
    *                v                                         |
-   *            V2_GET_FLAGS                                  |
+   *            V2_GET_PARENT                                 |
    *                |                                         |
    *                v (skip if not enabled)                   |
    *            V2_GET_OP_FEATURES                            |
@@ -66,16 +66,13 @@ private:
    *                v                                         |
    *            V2_GET_GROUP                                  |
    *                |                                         |
-   *                v                                         |
+   *                |     -EOPNOTSUPP                         |
+   *                |   * * * *                               |
+   *                |   *     *                               |
+   *                v   v     *                               |
    *            V2_GET_SNAPSHOTS (skip if no snaps)           |
-   *                |       .                                 |
-   *                |       v (pre-mimic OSD)                 |
-   *                |   V2_GET_SNAPSHOTS_LEGACY               |
-   *                |       |                                 |
-   *                |       v                                 |
-   *                |   V2_GET_SNAP_TIMESTAMPS                |
-   *                |       |                                 |
-   *                v       v                                 |
+   *                |                                         |
+   *                v                                         |
    *            V2_REFRESH_PARENT (skip if no parent or       |
    *                |              refresh not needed)        |
    *                v                                         |
@@ -132,6 +129,8 @@ private:
 
   bufferlist m_out_bl;
 
+  bool m_legacy_snapshot = false;
+
   uint8_t m_order = 0;
   uint64_t m_size = 0;
   uint64_t m_features = 0;
@@ -178,12 +177,12 @@ private:
   void send_v2_get_mutable_metadata();
   Context *handle_v2_get_mutable_metadata(int *result);
 
+  void send_v2_get_parent();
+  Context *handle_v2_get_parent(int *result);
+
   void send_v2_get_metadata();
   Context *handle_v2_get_metadata(int *result);
 
-  void send_v2_get_flags();
-  Context *handle_v2_get_flags(int *result);
-
   void send_v2_get_op_features();
   Context *handle_v2_get_op_features(int *result);
 
@@ -196,9 +195,6 @@ private:
   void send_v2_get_snapshots_legacy();
   Context *handle_v2_get_snapshots_legacy(int *result);
 
-  void send_v2_get_snap_timestamps();
-  Context *handle_v2_get_snap_timestamps(int *result);
-
   void send_v2_refresh_parent();
   Context *handle_v2_refresh_parent(int *result);
 
index dcb0661fbd1b2f3c77eda48ebe7d8fed8b8f1d7d..51bc9ffd00469e8c15ce70817bf15fbfd7c38f75 100644 (file)
@@ -115,7 +115,7 @@ void SnapshotRemoveRequest<I>::get_snap() {
   ldout(cct, 5) << dendl;
 
   librados::ObjectReadOperation op;
-  cls_client::snapshot_info_get_start(&op, m_snap_id);
+  cls_client::snapshot_get_start(&op, m_snap_id);
 
   auto aio_comp = create_rados_callback<
     SnapshotRemoveRequest<I>,
@@ -136,7 +136,7 @@ void SnapshotRemoveRequest<I>::handle_get_snap(int r) {
     cls::rbd::SnapshotInfo snap_info;
 
     auto it = m_out_bl.cbegin();
-    r = cls_client::snapshot_info_get_finish(&it, &snap_info);
+    r = cls_client::snapshot_get_finish(&it, &snap_info);
     if (r == 0) {
       m_child_attached = (snap_info.child_count > 0);
     }
index 0e1175ac3d07bb75c5fd1ee1e34b72086a8cb299..77596dd690b548b6effcfa69c15e83dbbeb89b0a 100644 (file)
@@ -3,7 +3,6 @@ add_executable(ceph_test_cls_rbd
   test_cls_rbd.cc
   $<TARGET_OBJECTS:common_texttable_obj>)
 target_link_libraries(ceph_test_cls_rbd
-  librbd
   cls_rbd_client
   cls_lock_client
   librados
index ea55689337fa8bc43aef8f8d5e431b8c413b2077..c03c4dfd81446180a7602046daeee12afe13de3a 100644 (file)
@@ -403,20 +403,14 @@ TEST_F(TestClsRbd, get_features)
   string oid = get_temp_image_name();
 
   uint64_t features;
-  ASSERT_EQ(-ENOENT, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  uint64_t incompatible_features;
+  ASSERT_EQ(-ENOENT, get_features(&ioctx, oid, false, &features,
+                                  &incompatible_features));
 
   ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid, -1));
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, false, &features,
+                            &incompatible_features));
   ASSERT_EQ(0u, features);
-
-  int r = get_features(&ioctx, oid, 1, &features);
-  if (r == 0) {
-    ASSERT_EQ(0u, features);
-  } else {
-    // deprecated snapshot handling
-    ASSERT_EQ(-ENOENT, r);
-  }
-
   ioctx.close();
 }
 
@@ -837,48 +831,35 @@ TEST_F(TestClsRbd, snapshots)
 
   ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, 0, oid, -1));
 
-  vector<cls::rbd::SnapshotInfo> snaps;
-  vector<string> snap_names;
-  vector<uint64_t> snap_sizes;
   SnapContext snapc;
-  vector<ParentInfo> parents;
-  vector<uint8_t> protection_status;
-  vector<utime_t> snap_timestamps;
+  cls::rbd::SnapshotInfo snap;
+  std::string snap_name;
+  uint64_t snap_size;
+  uint8_t snap_order;
+  ParentInfo parent;
+  uint8_t protection_status;
+  utime_t snap_timestamp;
 
   ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc));
   ASSERT_EQ(0u, snapc.snaps.size());
   ASSERT_EQ(0u, snapc.seq);
-  ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps,
-                            &parents, &protection_status));
-  ASSERT_EQ(0u, snaps.size());
-  ASSERT_EQ(0u, parents.size());
-  ASSERT_EQ(0u, protection_status.size());
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(0u, snap_names.size());
-  ASSERT_EQ(0u, snap_sizes.size());
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(0u, snap_timestamps.size());
 
   ASSERT_EQ(0, snapshot_add(&ioctx, oid, 0, "snap1"));
   ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc));
   ASSERT_EQ(1u, snapc.snaps.size());
   ASSERT_EQ(0u, snapc.snaps[0]);
   ASSERT_EQ(0u, snapc.seq);
-  ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps,
-                            &parents, &protection_status));
-  ASSERT_EQ(1u, snaps.size());
-  ASSERT_EQ(1u, parents.size());
-  ASSERT_EQ(1u, protection_status.size());
-  ASSERT_EQ("snap1", snaps[0].name);
-  ASSERT_EQ(userSnapNamespace, snaps[0].snapshot_namespace);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(1u, snap_names.size());
-  ASSERT_EQ("snap1", snap_names[0]);
-  ASSERT_EQ(10u, snap_sizes[0]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(1u, snap_timestamps.size());
+
+  ASSERT_EQ(0, snapshot_get(&ioctx, oid, 0, &snap));
+  ASSERT_EQ("snap1", snap.name);
+  ASSERT_EQ(userSnapNamespace, snap.snapshot_namespace);
+  ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, 0, &snap_name));
+  ASSERT_EQ("snap1", snap_name);
+  ASSERT_EQ(0, get_size(&ioctx, oid, 0, &snap_size, &snap_order));
+  ASSERT_EQ(10U, snap_size);
+  ASSERT_EQ(0, get_parent(&ioctx, oid, 0, &parent.spec, &parent.overlap));
+  ASSERT_EQ(0, get_protection_status(&ioctx, oid, 0, &protection_status));
+  ASSERT_EQ(0, get_snapshot_timestamp(&ioctx, oid, 0, &snap_timestamp));
 
   // snap with same id and name
   ASSERT_EQ(-EEXIST, snapshot_add(&ioctx, oid, 0, "snap1"));
@@ -886,14 +867,6 @@ TEST_F(TestClsRbd, snapshots)
   ASSERT_EQ(1u, snapc.snaps.size());
   ASSERT_EQ(0u, snapc.snaps[0]);
   ASSERT_EQ(0u, snapc.seq);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(1u, snap_names.size());
-  ASSERT_EQ("snap1", snap_names[0]);
-  ASSERT_EQ(10u, snap_sizes[0]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(1u, snap_timestamps.size());
-
 
   // snap with same id, different name
   ASSERT_EQ(-EEXIST, snapshot_add(&ioctx, oid, 0, "snap2"));
@@ -901,13 +874,6 @@ TEST_F(TestClsRbd, snapshots)
   ASSERT_EQ(1u, snapc.snaps.size());
   ASSERT_EQ(0u, snapc.snaps[0]);
   ASSERT_EQ(0u, snapc.seq);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(1u, snap_names.size());
-  ASSERT_EQ("snap1", snap_names[0]);
-  ASSERT_EQ(10u, snap_sizes[0]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(1u, snap_timestamps.size());
 
   // snap with different id, same name
   ASSERT_EQ(-EEXIST, snapshot_add(&ioctx, oid, 1, "snap1"));
@@ -915,13 +881,6 @@ TEST_F(TestClsRbd, snapshots)
   ASSERT_EQ(1u, snapc.snaps.size());
   ASSERT_EQ(0u, snapc.snaps[0]);
   ASSERT_EQ(0u, snapc.seq);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(snap_names.size(), 1u);
-  ASSERT_EQ(snap_names[0], "snap1");
-  ASSERT_EQ(snap_sizes[0], 10u);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(1u, snap_timestamps.size());
 
   // snap with different id, different name
   ASSERT_EQ(0, snapshot_add(&ioctx, oid, 1, "snap2"));
@@ -930,55 +889,29 @@ TEST_F(TestClsRbd, snapshots)
   ASSERT_EQ(1u, snapc.snaps[0]);
   ASSERT_EQ(0u, snapc.snaps[1]);
   ASSERT_EQ(1u, snapc.seq);
-  ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps,
-                            &parents, &protection_status));
-  ASSERT_EQ(2u, snaps.size());
-  ASSERT_EQ(2u, parents.size());
-  ASSERT_EQ(2u, protection_status.size());
-  ASSERT_EQ("snap2", snaps[0].name);
-  ASSERT_EQ("snap1", snaps[1].name);
-  ASSERT_EQ(userSnapNamespace, snaps[0].snapshot_namespace);
-  ASSERT_EQ(userSnapNamespace, snaps[1].snapshot_namespace);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(2u, snap_names.size());
-  ASSERT_EQ("snap2", snap_names[0]);
-  ASSERT_EQ(10u, snap_sizes[0]);
-  ASSERT_EQ("snap1", snap_names[1]);
-  ASSERT_EQ(10u, snap_sizes[1]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(2u, snap_timestamps.size());
+
+  ASSERT_EQ(0, snapshot_get(&ioctx, oid, 1, &snap));
+  ASSERT_EQ("snap2", snap.name);
+  ASSERT_EQ(userSnapNamespace, snap.snapshot_namespace);
+  ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, 1, &snap_name));
+  ASSERT_EQ("snap2", snap_name);
+  ASSERT_EQ(0, get_size(&ioctx, oid, 1, &snap_size, &snap_order));
+  ASSERT_EQ(10U, snap_size);
+  ASSERT_EQ(0, get_parent(&ioctx, oid, 1, &parent.spec, &parent.overlap));
+  ASSERT_EQ(0, get_protection_status(&ioctx, oid, 1, &protection_status));
+  ASSERT_EQ(0, get_snapshot_timestamp(&ioctx, oid, 1, &snap_timestamp));
 
   ASSERT_EQ(0, snapshot_rename(&ioctx, oid, 0, "snap1-rename"));
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(2u, snap_names.size());
-  ASSERT_EQ("snap2", snap_names[0]);
-  ASSERT_EQ(10u, snap_sizes[0]);
-  ASSERT_EQ("snap1-rename", snap_names[1]);
-  ASSERT_EQ(10u, snap_sizes[1]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(2u, snap_timestamps.size());
+  ASSERT_EQ(0, snapshot_get(&ioctx, oid, 0, &snap));
+  ASSERT_EQ("snap1-rename", snap.name);
+  ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, 0, &snap_name));
+  ASSERT_EQ("snap1-rename", snap_name);
 
   ASSERT_EQ(0, snapshot_remove(&ioctx, oid, 0));
   ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc));
   ASSERT_EQ(1u, snapc.snaps.size());
   ASSERT_EQ(1u, snapc.snaps[0]);
   ASSERT_EQ(1u, snapc.seq);
-  ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps,
-                            &parents, &protection_status));
-  ASSERT_EQ(1u, snaps.size());
-  ASSERT_EQ(1u, parents.size());
-  ASSERT_EQ(1u, protection_status.size());
-  ASSERT_EQ("snap2", snaps[0].name);
-  ASSERT_EQ(userSnapNamespace, snaps[0].snapshot_namespace);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(1u, snap_names.size());
-  ASSERT_EQ("snap2", snap_names[0]);
-  ASSERT_EQ(10u, snap_sizes[0]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(1u, snap_timestamps.size());
 
   uint64_t size;
   uint8_t order;
@@ -994,76 +927,30 @@ TEST_F(TestClsRbd, snapshots)
   ASSERT_EQ(large_snap_id, snapc.snaps[0]);
   ASSERT_EQ(1u, snapc.snaps[1]);
   ASSERT_EQ(large_snap_id, snapc.seq);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(2u, snap_names.size());
-  ASSERT_EQ("snap3", snap_names[0]);
-  ASSERT_EQ(0u, snap_sizes[0]);
-  ASSERT_EQ("snap2", snap_names[1]);
-  ASSERT_EQ(10u, snap_sizes[1]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(2u, snap_timestamps.size());
-
-  ASSERT_EQ(0, get_size(&ioctx, oid, large_snap_id, &size, &order));
-  ASSERT_EQ(0u, size);
-  ASSERT_EQ(22u, order);
 
-  ASSERT_EQ(0, get_size(&ioctx, oid, 1, &size, &order));
-  ASSERT_EQ(10u, size);
-  ASSERT_EQ(22u, order);
+  ASSERT_EQ(0, snapshot_get(&ioctx, oid, large_snap_id, &snap));
+  ASSERT_EQ("snap3", snap.name);
+  ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, large_snap_id, &snap_name));
+  ASSERT_EQ("snap3", snap_name);
+  ASSERT_EQ(0, get_size(&ioctx, oid, large_snap_id, &snap_size, &snap_order));
+  ASSERT_EQ(0U, snap_size);
+  ASSERT_EQ(22u, snap_order);
+
+  ASSERT_EQ(0, get_size(&ioctx, oid, 1, &snap_size, &snap_order));
+  ASSERT_EQ(10u, snap_size);
+  ASSERT_EQ(22u, snap_order);
 
   ASSERT_EQ(0, snapshot_remove(&ioctx, oid, large_snap_id));
   ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc));
   ASSERT_EQ(1u, snapc.snaps.size());
   ASSERT_EQ(1u, snapc.snaps[0]);
   ASSERT_EQ(large_snap_id, snapc.seq);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(1u, snap_names.size());
-  ASSERT_EQ("snap2", snap_names[0]);
-  ASSERT_EQ(10u, snap_sizes[0]);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(1u, snap_timestamps.size());
 
   ASSERT_EQ(-ENOENT, snapshot_remove(&ioctx, oid, large_snap_id));
   ASSERT_EQ(0, snapshot_remove(&ioctx, oid, 1));
   ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc));
   ASSERT_EQ(0u, snapc.snaps.size());
   ASSERT_EQ(large_snap_id, snapc.seq);
-  ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names,
-                            &snap_sizes, &parents, &protection_status));
-  ASSERT_EQ(0u, snap_names.size());
-  ASSERT_EQ(0u, snap_sizes.size());
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(0u, snap_timestamps.size());
-
-  ioctx.close();
-}
-
-TEST_F(TestClsRbd, snapshots_timestamps)
-{
-  librados::IoCtx ioctx;
-  ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
-
-  string oid = get_temp_image_name();
-
-  ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, 0, oid, -1));
-
-  vector<utime_t> snap_timestamps;
-  SnapContext snapc;
-
-  ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc));
-  ASSERT_EQ(0u, snapc.snaps.size());
-  ASSERT_EQ(0u, snapc.seq);
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_EQ(0u, snap_timestamps.size());
-
-  ASSERT_EQ(0, snapshot_add(&ioctx, oid, 0, "snap1"));
-
-  ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc));
-  ASSERT_EQ(1u, snapc.snaps.size());
-  ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps));
-  ASSERT_LT(0U, snap_timestamps[0].tv.tv_sec);
   ioctx.close();
 }
 
@@ -1124,41 +1011,6 @@ TEST_F(TestClsRbd, stripingv2)
   ioctx.close();
 }
 
-TEST_F(TestClsRbd, get_mutable_metadata_features)
-{
-  librados::IoCtx ioctx;
-  ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
-
-  string oid = get_temp_image_name();
-  ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, RBD_FEATURE_EXCLUSIVE_LOCK,
-                            oid, -1));
-
-  uint64_t size, features, incompatible_features;
-  std::map<rados::cls::lock::locker_id_t,
-           rados::cls::lock::locker_info_t> lockers;
-  bool exclusive_lock;
-  std::string lock_tag;
-  ::SnapContext snapc;
-  ParentInfo parent;
-
-  ASSERT_EQ(0, get_mutable_metadata(&ioctx, oid, true, &size, &features,
-                                   &incompatible_features, &lockers,
-                                   &exclusive_lock, &lock_tag, &snapc,
-                                    &parent));
-  ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK), features);
-  ASSERT_EQ(0U, incompatible_features);
-
-  ASSERT_EQ(0, get_mutable_metadata(&ioctx, oid, false, &size, &features,
-                                    &incompatible_features, &lockers,
-                                    &exclusive_lock, &lock_tag, &snapc,
-                                   &parent));
-  ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK), features);
-  ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK),
-           incompatible_features);
-
-  ioctx.close();
-}
-
 TEST_F(TestClsRbd, object_map_save)
 {
   librados::IoCtx ioctx;
@@ -1381,29 +1233,24 @@ TEST_F(TestClsRbd, flags)
   ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid, -1));
 
   uint64_t flags;
-  std::vector<snapid_t> snap_ids;
-  std::vector<uint64_t> snap_flags;
-  ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
+  ASSERT_EQ(0, get_flags(&ioctx, oid, CEPH_NOSNAP, &flags));
   ASSERT_EQ(0U, flags);
 
   librados::ObjectWriteOperation op1;
   set_flags(&op1, CEPH_NOSNAP, 3, 2);
   ASSERT_EQ(0, ioctx.operate(oid, &op1));
-  ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
+  ASSERT_EQ(0, get_flags(&ioctx, oid, CEPH_NOSNAP, &flags));
   ASSERT_EQ(2U, flags);
 
   uint64_t snap_id = 10;
-  snap_ids.push_back(snap_id);
-  ASSERT_EQ(-ENOENT, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
+  ASSERT_EQ(-ENOENT, get_flags(&ioctx, oid, snap_id, &flags));
   ASSERT_EQ(0, snapshot_add(&ioctx, oid, snap_id, "snap"));
 
   librados::ObjectWriteOperation op2;
   set_flags(&op2, snap_id, 31, 4);
   ASSERT_EQ(0, ioctx.operate(oid, &op2));
-  ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags));
-  ASSERT_EQ(2U, flags);
-  ASSERT_EQ(snap_ids.size(), snap_flags.size());
-  ASSERT_EQ(6U, snap_flags[0]);
+  ASSERT_EQ(0, get_flags(&ioctx, oid, snap_id, &flags));
+  ASSERT_EQ(6U, flags);
 
   ioctx.close();
 }
@@ -1486,7 +1333,9 @@ TEST_F(TestClsRbd, set_features)
   ASSERT_EQ(0, set_features(&ioctx, oid, features, mask));
 
   uint64_t actual_features;
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &actual_features));
+  uint64_t incompatible_features;
+  ASSERT_EQ(0, get_features(&ioctx, oid, true, &actual_features,
+                            &incompatible_features));
 
   uint64_t expected_features = RBD_FEATURES_MUTABLE | base_features;
   ASSERT_EQ(expected_features, actual_features);
@@ -1495,7 +1344,8 @@ TEST_F(TestClsRbd, set_features)
   mask = RBD_FEATURE_OBJECT_MAP;
   ASSERT_EQ(0, set_features(&ioctx, oid, features, mask));
 
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &actual_features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, true, &actual_features,
+                            &incompatible_features));
 
   expected_features = (RBD_FEATURES_MUTABLE | base_features) &
                       ~RBD_FEATURE_OBJECT_MAP;
@@ -2606,7 +2456,9 @@ TEST_F(TestClsRbd, op_features)
   ASSERT_EQ(0u, actual_op_features);
 
   uint64_t features;
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  uint64_t incompatible_features;
+  ASSERT_EQ(0, get_features(&ioctx, oid, true, &features,
+                            &incompatible_features));
   ASSERT_EQ(0u, features);
 
   op_features = RBD_OPERATION_FEATURES_ALL;
@@ -2615,7 +2467,8 @@ TEST_F(TestClsRbd, op_features)
   ASSERT_EQ(0, op_features_get(&ioctx, oid, &actual_op_features));
   ASSERT_EQ(mask, actual_op_features);
 
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, true, &features,
+                            &incompatible_features));
   ASSERT_EQ(RBD_FEATURE_OPERATIONS, features);
 
   op_features = 0;
@@ -2629,7 +2482,8 @@ TEST_F(TestClsRbd, op_features)
 
   mask = RBD_OPERATION_FEATURES_ALL;
   ASSERT_EQ(0, op_features_set(&ioctx, oid, op_features, mask));
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, true, &features,
+                            &incompatible_features));
   ASSERT_EQ(0u, features);
 }
 
@@ -2651,13 +2505,9 @@ TEST_F(TestClsRbd, clone_parent)
   ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "image2"}));
   ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {2, "image2"}));
 
-  std::vector<cls::rbd::SnapshotInfo> snaps;
-  std::vector<ParentInfo> parents;
-  std::vector<uint8_t> protection_status;
-  ASSERT_EQ(0, snapshot_get(&ioctx, oid, {123}, &snaps,
-                            &parents, &protection_status));
-  ASSERT_EQ(1U, snaps.size());
-  ASSERT_EQ(3U, snaps[0].child_count);
+  cls::rbd::SnapshotInfo snap;
+  ASSERT_EQ(0, snapshot_get(&ioctx, oid, 123, &snap));
+  ASSERT_EQ(3U, snap.child_count);
 
   // op feature should have been enabled
   uint64_t op_features;
@@ -2687,11 +2537,9 @@ TEST_F(TestClsRbd, clone_parent)
   librados::ObjectWriteOperation op3;
   ::librbd::cls_client::snapshot_trash_add(&op3, 123);
   ASSERT_EQ(0, ioctx.operate(oid, &op3));
-  ASSERT_EQ(0, snapshot_get(&ioctx, oid, {123}, &snaps,
-                            &parents, &protection_status));
-  ASSERT_EQ(1U, snaps.size());
+  ASSERT_EQ(0, snapshot_get(&ioctx, oid, 123, &snap));
   ASSERT_EQ(cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH,
-            cls::rbd::get_snap_namespace_type(snaps[0].snapshot_namespace));
+            cls::rbd::get_snap_namespace_type(snap.snapshot_namespace));
 
   expected_op_features |= RBD_OPERATION_FEATURE_SNAP_TRASH;
   ASSERT_EQ(0, op_features_get(&ioctx, oid, &op_features));
@@ -2810,14 +2658,17 @@ TEST_F(TestClsRbd, migration)
   ASSERT_EQ(-EINVAL, migration_get(&ioctx, oid, &read_migration_spec));
 
   uint64_t features;
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  uint64_t incompatible_features;
+  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features,
+                            &incompatible_features));
   ASSERT_EQ(0U, features);
 
   ASSERT_EQ(0, migration_set(&ioctx, oid, migration_spec));
   ASSERT_EQ(0, migration_get(&ioctx, oid, &read_migration_spec));
   ASSERT_EQ(migration_spec, read_migration_spec);
 
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features,
+                            &incompatible_features));
   ASSERT_EQ(RBD_FEATURE_MIGRATING, features);
 
   ASSERT_EQ(-EEXIST, migration_set(&ioctx, oid, migration_spec));
@@ -2831,7 +2682,8 @@ TEST_F(TestClsRbd, migration)
 
   ASSERT_EQ(0, migration_remove(&ioctx, oid));
 
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features,
+                            &incompatible_features));
   ASSERT_EQ(0U, features);
 
   ASSERT_EQ(-EINVAL, migration_get(&ioctx, oid, &read_migration_spec));
@@ -2842,13 +2694,15 @@ TEST_F(TestClsRbd, migration)
 
   ASSERT_EQ(0, migration_set(&ioctx, oid, migration_spec));
 
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features,
+                            &incompatible_features));
   ASSERT_EQ(RBD_FEATURE_MIGRATING, features);
 
   ASSERT_EQ(0, migration_remove(&ioctx, oid));
 
   ASSERT_EQ(-EINVAL, migration_get(&ioctx, oid, &read_migration_spec));
-  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features));
+  ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features,
+                            &incompatible_features));
   ASSERT_EQ(0U, features);
 
   ioctx.close();
index 51340526558ab9f9db263e0758a2cd65101f3f55..d3dcf5e0e5cf8701e55f7501f0e9e045ab5b1029 100644 (file)
@@ -202,14 +202,15 @@ public:
                                            encode(incompatible, *out_bl);
                                            return 0;
                                          })));
+      expect_get_flags(mock_image_ctx, 0);
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
                   exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapcontext"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _))
                     .WillOnce(DoDefault());
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                  exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _))
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
                     .WillOnce(DoDefault());
     }
   }
@@ -276,6 +277,7 @@ public:
       expect.WillOnce(Return(r));
     } else {
       expect.WillOnce(DoDefault());
+      expect_get_flags(mock_image_ctx, 0);
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
                   exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
                     .WillOnce(DoDefault());
@@ -295,6 +297,10 @@ public:
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
                   exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_size"), _, _, _))
                     .WillOnce(DoDefault());
+      EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
+                  exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_timestamp"), _, _, _))
+                    .WillOnce(DoDefault());
+      expect_get_flags(mock_image_ctx, 0);
       EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
                   exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _))
                     .WillOnce(DoDefault());
@@ -304,16 +310,6 @@ public:
     }
   }
 
-  void expect_snap_timestamp_list(MockRefreshImageCtx &mock_image_ctx, int r) {
-    auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
-                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_timestamp"), _, _, _));
-       if (r < 0) {
-      expect.WillOnce(Return(r));
-    } else {
-      expect.WillOnce(DoDefault());
-    }
-  }
-
   void expect_apply_metadata(MockRefreshImageCtx &mock_image_ctx,
                             int r) {
     EXPECT_CALL(mock_image_ctx, apply_metadata(_, false))
@@ -513,7 +509,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessV2) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
@@ -544,8 +539,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV2) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_get_snapshots(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@@ -578,12 +571,9 @@ TEST_F(TestMockImageRefreshRequest, SuccessLegacySnapshotV2) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_get_snapshots(mock_image_ctx, -EOPNOTSUPP);
   expect_get_snapshots_legacy(mock_image_ctx, 0);
-  expect_snap_timestamp_list(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
     expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
@@ -617,8 +607,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_get_snapshots(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@@ -671,7 +659,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessChild) {
   expect_get_mutable_metadata(mock_image_ctx, ictx2->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_op_features(mock_image_ctx, RBD_OPERATION_FEATURE_CLONE_CHILD, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(*mock_refresh_parent_request, true);
@@ -724,7 +711,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessChildDontOpenParent) {
   expect_get_mutable_metadata(mock_image_ctx, ictx2->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_op_features(mock_image_ctx, RBD_OPERATION_FEATURE_CLONE_CHILD, 0);
   expect_get_group(mock_image_ctx, 0);
   if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
@@ -756,7 +742,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessOpFeatures) {
   expect_get_mutable_metadata(mock_image_ctx, mock_image_ctx.features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_op_features(mock_image_ctx, 4096, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
@@ -826,7 +811,6 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLock) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   expect_shut_down_exclusive_lock(mock_image_ctx, *mock_exclusive_lock, 0);
@@ -881,7 +865,6 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLockWhileAcquiringLock) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
 
@@ -926,7 +909,6 @@ TEST_F(TestMockImageRefreshRequest, JournalDisabledByPolicy) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
 
@@ -976,7 +958,6 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithExclusiveLock) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
 
@@ -1025,7 +1006,6 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithoutExclusiveLock) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   expect_set_require_lock(mock_image_ctx, librbd::io::DIRECTION_BOTH, true);
@@ -1072,7 +1052,6 @@ TEST_F(TestMockImageRefreshRequest, DisableJournal) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   expect_block_writes(mock_image_ctx, 0);
@@ -1119,7 +1098,6 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithExclusiveLock) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   expect_open_object_map(mock_image_ctx, &mock_object_map, 0);
@@ -1159,7 +1137,6 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithoutExclusiveLock) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
 
@@ -1210,7 +1187,6 @@ TEST_F(TestMockImageRefreshRequest, DisableObjectMap) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   expect_close_object_map(mock_image_ctx, *mock_object_map, 0);
@@ -1252,7 +1228,6 @@ TEST_F(TestMockImageRefreshRequest, OpenObjectMapError) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, 0);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   expect_open_object_map(mock_image_ctx, mock_object_map, -EFBIG);
@@ -1281,7 +1256,6 @@ TEST_F(TestMockImageRefreshRequest, ApplyMetadataError) {
   expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0);
   expect_get_metadata(mock_image_ctx, 0);
   expect_apply_metadata(mock_image_ctx, -EINVAL);
-  expect_get_flags(mock_image_ctx, 0);
   expect_get_group(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {