} BOOST_SCOPE_EXIT_END;
std::vector<librbd::snap_info_t> snaps;
- r = snap_list(dst_image_ctx, snaps);
+ r = Snapshot<I>::list(dst_image_ctx, snaps);
if (r < 0) {
lderr(m_cct) << "failed listing snapshots: " << cpp_strerror(r)
<< dendl;
for (auto &snap : snaps) {
librbd::NoOpProgressContext prog_ctx;
- int r = snap_remove(dst_image_ctx, snap.name.c_str(),
- RBD_SNAP_REMOVE_UNPROTECT, prog_ctx);
+ int r = Snapshot<I>::remove(dst_image_ctx, snap.name.c_str(),
+ RBD_SNAP_REMOVE_UNPROTECT, prog_ctx);
if (r < 0) {
lderr(m_cct) << "failed removing snapshot: " << cpp_strerror(r)
<< dendl;
int Migration<I>::list_src_snaps(std::vector<librbd::snap_info_t> *snaps) {
ldout(m_cct, 10) << dendl;
- int r = snap_list(m_src_image_ctx, *snaps);
+ int r = Snapshot<I>::list(m_src_image_ctx, *snaps);
if (r < 0) {
lderr(m_cct) << "failed listing snapshots: " << cpp_strerror(r) << dendl;
return r;
auto &snap = *it;
librbd::NoOpProgressContext prog_ctx;
- int r = snap_remove(m_src_image_ctx, snap.name.c_str(),
- RBD_SNAP_REMOVE_UNPROTECT, prog_ctx);
+ int r = Snapshot<I>::remove(m_src_image_ctx, snap.name.c_str(),
+ RBD_SNAP_REMOVE_UNPROTECT, prog_ctx);
if (r < 0) {
lderr(m_cct) << "failed removing source image snapshot '" << snap.name
<< "': " << cpp_strerror(r) << dendl;
#include "librbd/api/Snapshot.h"
#include "cls/rbd/cls_rbd_types.h"
#include "common/errno.h"
+#include "librbd/internal.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
#include "librbd/Operations.h"
#include "librbd/Utils.h"
+#include "librbd/api/Image.h"
#include <boost/variant.hpp>
#include "include/Context.h"
#include "common/Cond.h"
#undef dout_prefix
#define dout_prefix *_dout << "librbd::api::Snapshot: " << __func__ << ": "
+using librados::snap_t;
+
namespace librbd {
namespace api {
return 0;
}
+template <typename I>
+int Snapshot<I>::list(I *ictx, vector<snap_info_t>& snaps) {
+ ldout(ictx->cct, 20) << "snap_list " << ictx << dendl;
+
+ int r = ictx->state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ std::shared_lock l{ictx->image_lock};
+ for (auto &it : ictx->snap_info) {
+ snap_info_t info;
+ info.name = it.second.name;
+ info.id = it.first;
+ info.size = it.second.size;
+ snaps.push_back(info);
+ }
+
+ return 0;
+}
+
+template <typename I>
+int Snapshot<I>::exists(I *ictx, const cls::rbd::SnapshotNamespace& snap_namespace,
+ const char *snap_name, bool *exists) {
+ ldout(ictx->cct, 20) << "snap_exists " << ictx << " " << snap_name << dendl;
+
+ int r = ictx->state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ std::shared_lock l{ictx->image_lock};
+ *exists = ictx->get_snap_id(snap_namespace, snap_name) != CEPH_NOSNAP;
+ return 0;
+}
+
+template <typename I>
+int Snapshot<I>::remove(I *ictx, const char *snap_name, uint32_t flags,
+ ProgressContext& pctx) {
+ ldout(ictx->cct, 20) << "snap_remove " << ictx << " " << snap_name << " flags: " << flags << dendl;
+
+ int r = 0;
+
+ r = ictx->state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ if (flags & RBD_SNAP_REMOVE_FLATTEN) {
+ r = Image<I>::flatten_children(ictx, snap_name, pctx);
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ bool protect;
+ r = is_protected(ictx, snap_name, &protect);
+ if (r < 0) {
+ return r;
+ }
+
+ if (protect && flags & RBD_SNAP_REMOVE_UNPROTECT) {
+ r = ictx->operations->snap_unprotect(cls::rbd::UserSnapshotNamespace(), snap_name);
+ if (r < 0) {
+ lderr(ictx->cct) << "failed to unprotect snapshot: " << snap_name << dendl;
+ return r;
+ }
+
+ r = is_protected(ictx, snap_name, &protect);
+ if (r < 0) {
+ return r;
+ }
+ if (protect) {
+ lderr(ictx->cct) << "snapshot is still protected after unprotection" << dendl;
+ ceph_abort();
+ }
+ }
+
+ C_SaferCond ctx;
+ ictx->operations->snap_remove(cls::rbd::UserSnapshotNamespace(), snap_name, &ctx);
+
+ r = ctx.wait();
+ return r;
+}
+
+template <typename I>
+int Snapshot<I>::get_timestamp(I *ictx, uint64_t snap_id, struct timespec *timestamp) {
+ auto snap_it = ictx->snap_info.find(snap_id);
+ ceph_assert(snap_it != ictx->snap_info.end());
+ utime_t time = snap_it->second.timestamp;
+ time.to_timespec(timestamp);
+ return 0;
+}
+
+template <typename I>
+int Snapshot<I>::get_limit(I *ictx, uint64_t *limit) {
+ int r = cls_client::snapshot_get_limit(&ictx->md_ctx, ictx->header_oid,
+ limit);
+ if (r == -EOPNOTSUPP) {
+ *limit = UINT64_MAX;
+ r = 0;
+ }
+ return r;
+}
+
+template <typename I>
+int Snapshot<I>::set_limit(I *ictx, uint64_t limit) {
+ return ictx->operations->snap_set_limit(limit);
+}
+
+template <typename I>
+int Snapshot<I>::is_protected(I *ictx, const char *snap_name, bool *protect) {
+ ldout(ictx->cct, 20) << "snap_is_protected " << ictx << " " << snap_name
+ << dendl;
+
+ int r = ictx->state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ std::shared_lock l{ictx->image_lock};
+ snap_t snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(), snap_name);
+ if (snap_id == CEPH_NOSNAP)
+ return -ENOENT;
+ bool is_unprotected;
+ r = ictx->is_snap_unprotected(snap_id, &is_unprotected);
+ // consider both PROTECTED or UNPROTECTING to be 'protected',
+ // since in either state they can't be deleted
+ *protect = !is_unprotected;
+ return r;
+}
+
+template <typename I>
+int Snapshot<I>::get_namespace(I *ictx, const char *snap_name,
+ cls::rbd::SnapshotNamespace *snap_namespace) {
+ ldout(ictx->cct, 20) << "get_snap_namespace " << ictx << " " << snap_name
+ << dendl;
+
+ int r = ictx->state->refresh_if_required();
+ if (r < 0)
+ return r;
+ std::shared_lock l{ictx->image_lock};
+ snap_t snap_id = ictx->get_snap_id(*snap_namespace, snap_name);
+ if (snap_id == CEPH_NOSNAP)
+ return -ENOENT;
+ r = ictx->get_snap_namespace(snap_id, snap_namespace);
+ return r;
+}
+
} // namespace api
} // namespace librbd
#define CEPH_LIBRBD_API_SNAPSHOT_H
#include "include/rbd/librbd.hpp"
+#include "cls/rbd/cls_rbd_types.h"
#include <string>
namespace librbd {
static int get_id(ImageCtxT *ictx, const std::string& snap_name, uint64_t *snap_id);
+ static int list(ImageCtxT *ictx, std::vector<snap_info_t>& snaps);
+
+ static int exists(ImageCtxT *ictx, const cls::rbd::SnapshotNamespace& snap_namespace,
+ const char *snap_name, bool *exists);
+
+ static int remove(ImageCtxT *ictx, const char *snap_name, uint32_t flags, ProgressContext& pctx);
+
+ static int get_limit(ImageCtxT *ictx, uint64_t *limit);
+
+ static int set_limit(ImageCtxT *ictx, uint64_t limit);
+
+ static int get_timestamp(ImageCtxT *ictx, uint64_t snap_id, struct timespec *timestamp);
+
+ static int is_protected(ImageCtxT *ictx, const char *snap_name, bool *protect);
+
+ static int get_namespace(ImageCtxT *ictx, const char *snap_name,
+ cls::rbd::SnapshotNamespace *snap_namespace);
+
};
} // namespace api
return (*opts_)->empty();
}
- int flatten_children(ImageCtx *ictx, const char* snap_name,
- ProgressContext& pctx)
- {
- CephContext *cct = ictx->cct;
- ldout(cct, 20) << "children flatten " << ictx->name << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0) {
- return r;
- }
-
- std::shared_lock l{ictx->image_lock};
- snap_t snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(),
- snap_name);
-
- cls::rbd::ParentImageSpec parent_spec{ictx->md_ctx.get_id(),
- ictx->md_ctx.get_namespace(),
- ictx->id, snap_id};
- std::vector<librbd::linked_image_spec_t> child_images;
- r = api::Image<>::list_children(ictx, parent_spec, &child_images);
- if (r < 0) {
- return r;
- }
-
- size_t size = child_images.size();
- if (size == 0) {
- return 0;
- }
-
- librados::IoCtx child_io_ctx;
- int64_t child_pool_id = -1;
- size_t i = 0;
- for (auto &child_image : child_images){
- std::string pool = child_image.pool_name;
- if (child_pool_id == -1 ||
- child_pool_id != child_image.pool_id ||
- child_io_ctx.get_namespace() != child_image.pool_namespace) {
- r = util::create_ioctx(ictx->md_ctx, "child image",
- child_image.pool_id, child_image.pool_namespace,
- &child_io_ctx);
- if (r < 0) {
- return r;
- }
-
- child_pool_id = child_image.pool_id;
- }
-
- ImageCtx *imctx = new ImageCtx("", child_image.image_id, nullptr,
- child_io_ctx, false);
- r = imctx->state->open(0);
- if (r < 0) {
- lderr(cct) << "error opening image: " << cpp_strerror(r) << dendl;
- return r;
- }
-
- if ((imctx->features & RBD_FEATURE_DEEP_FLATTEN) == 0 &&
- !imctx->snaps.empty()) {
- lderr(cct) << "snapshot in-use by " << pool << "/" << imctx->name
- << dendl;
- imctx->state->close();
- return -EBUSY;
- }
-
- librbd::NoOpProgressContext prog_ctx;
- r = imctx->operations->flatten(prog_ctx);
- if (r < 0) {
- lderr(cct) << "error flattening image: " << pool << "/"
- << (child_image.pool_namespace.empty() ?
- "" : "/" + child_image.pool_namespace)
- << child_image.image_name << cpp_strerror(r) << dendl;
- imctx->state->close();
- return r;
- }
-
- r = imctx->state->close();
- if (r < 0) {
- lderr(cct) << "failed to close image: " << cpp_strerror(r) << dendl;
- return r;
- }
-
- pctx.update_progress(++i, size);
- ceph_assert(i <= size);
- }
-
- return 0;
- }
-
- int get_snap_namespace(ImageCtx *ictx,
- const char *snap_name,
- cls::rbd::SnapshotNamespace *snap_namespace) {
- ldout(ictx->cct, 20) << "get_snap_namespace " << ictx << " " << snap_name
- << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
- std::shared_lock l{ictx->image_lock};
- snap_t snap_id = ictx->get_snap_id(*snap_namespace, snap_name);
- if (snap_id == CEPH_NOSNAP)
- return -ENOENT;
- r = ictx->get_snap_namespace(snap_id, snap_namespace);
- return r;
- }
-
- int snap_is_protected(ImageCtx *ictx, const char *snap_name, bool *is_protected)
- {
- ldout(ictx->cct, 20) << "snap_is_protected " << ictx << " " << snap_name
- << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- std::shared_lock l{ictx->image_lock};
- snap_t snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(), snap_name);
- if (snap_id == CEPH_NOSNAP)
- return -ENOENT;
- bool is_unprotected;
- r = ictx->is_snap_unprotected(snap_id, &is_unprotected);
- // consider both PROTECTED or UNPROTECTING to be 'protected',
- // since in either state they can't be deleted
- *is_protected = !is_unprotected;
- return r;
- }
-
int create_v1(IoCtx& io_ctx, const char *imgname, uint64_t size, int order)
{
CephContext *cct = (CephContext *)io_ctx.cct();
return 0;
}
- int snap_list(ImageCtx *ictx, vector<snap_info_t>& snaps)
- {
- ldout(ictx->cct, 20) << "snap_list " << ictx << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- std::shared_lock l{ictx->image_lock};
- for (map<snap_t, SnapInfo>::iterator it = ictx->snap_info.begin();
- it != ictx->snap_info.end(); ++it) {
- snap_info_t info;
- info.name = it->second.name;
- info.id = it->first;
- info.size = it->second.size;
- snaps.push_back(info);
- }
-
- return 0;
- }
-
- int snap_exists(ImageCtx *ictx, const cls::rbd::SnapshotNamespace& snap_namespace,
- const char *snap_name, bool *exists)
- {
- ldout(ictx->cct, 20) << "snap_exists " << ictx << " " << snap_name << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- std::shared_lock l{ictx->image_lock};
- *exists = ictx->get_snap_id(snap_namespace, snap_name) != CEPH_NOSNAP;
- return 0;
- }
-
- int snap_remove(ImageCtx *ictx, const char *snap_name, uint32_t flags,
- ProgressContext& pctx)
- {
- ldout(ictx->cct, 20) << "snap_remove " << ictx << " " << snap_name << " flags: " << flags << dendl;
-
- int r = 0;
-
- r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- if (flags & RBD_SNAP_REMOVE_FLATTEN) {
- r = flatten_children(ictx, snap_name, pctx);
- if (r < 0) {
- return r;
- }
- }
-
- bool is_protected;
- r = snap_is_protected(ictx, snap_name, &is_protected);
- if (r < 0) {
- return r;
- }
-
- if (is_protected && flags & RBD_SNAP_REMOVE_UNPROTECT) {
- r = ictx->operations->snap_unprotect(cls::rbd::UserSnapshotNamespace(), snap_name);
- if (r < 0) {
- lderr(ictx->cct) << "failed to unprotect snapshot: " << snap_name << dendl;
- return r;
- }
-
- r = snap_is_protected(ictx, snap_name, &is_protected);
- if (r < 0) {
- return r;
- }
- if (is_protected) {
- lderr(ictx->cct) << "snapshot is still protected after unprotection" << dendl;
- ceph_abort();
- }
- }
-
- C_SaferCond ctx;
- ictx->operations->snap_remove(cls::rbd::UserSnapshotNamespace(), snap_name, &ctx);
-
- r = ctx.wait();
- return r;
- }
-
- int snap_get_timestamp(ImageCtx *ictx, uint64_t snap_id, struct timespec *timestamp)
- {
- std::map<librados::snap_t, SnapInfo>::iterator snap_it = ictx->snap_info.find(snap_id);
- ceph_assert(snap_it != ictx->snap_info.end());
- utime_t time = snap_it->second.timestamp;
- time.to_timespec(timestamp);
- return 0;
- }
-
- int snap_get_limit(ImageCtx *ictx, uint64_t *limit)
- {
- int r = cls_client::snapshot_get_limit(&ictx->md_ctx, ictx->header_oid,
- limit);
- if (r == -EOPNOTSUPP) {
- *limit = UINT64_MAX;
- r = 0;
- }
- return r;
- }
-
- int snap_set_limit(ImageCtx *ictx, uint64_t limit)
- {
- return ictx->operations->snap_set_limit(limit);
- }
-
- struct CopyProgressCtx {
- explicit CopyProgressCtx(ProgressContext &p)
- : destictx(NULL), src_size(0), prog_ctx(p)
- { }
-
- ImageCtx *destictx;
- uint64_t src_size;
- ProgressContext &prog_ctx;
- };
-
int copy(ImageCtx *src, IoCtx& dest_md_ctx, const char *destname,
ImageOptions& opts, ProgressContext &prog_ctx, size_t sparse_size)
{
int lock_break(ImageCtx *ictx, rbd_lock_mode_t lock_mode,
const std::string &lock_owner);
- int snap_list(ImageCtx *ictx, std::vector<snap_info_t>& snaps);
- int snap_exists(ImageCtx *ictx, const cls::rbd::SnapshotNamespace& snap_namespace,
- const char *snap_name, bool *exists);
- int snap_get_limit(ImageCtx *ictx, uint64_t *limit);
- int snap_set_limit(ImageCtx *ictx, uint64_t limit);
- int snap_get_timestamp(ImageCtx *ictx, uint64_t snap_id, struct timespec *timestamp);
- int snap_remove(ImageCtx *ictx, const char *snap_name, uint32_t flags, ProgressContext& pctx);
- int snap_is_protected(ImageCtx *ictx, const char *snap_name,
- bool *is_protected);
int copy(ImageCtx *ictx, IoCtx& dest_md_ctx, const char *destname,
ImageOptions& opts, ProgressContext &prog_ctx, size_t sparse_size);
int copy(ImageCtx *src, ImageCtx *dest, ProgressContext &prog_ctx, size_t sparse_size);
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_remove_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::snap_remove(ictx, snap_name, 0, prog_ctx);
+ int r = librbd::api::Snapshot<>::remove(ictx, snap_name, 0, prog_ctx);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_remove2_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name, flags);
- int r = librbd::snap_remove(ictx, snap_name, flags, pctx);
+ int r = librbd::api::Snapshot<>::remove(ictx, snap_name, flags, pctx);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_is_protected_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_is_protected(ictx, snap_name, is_protected);
+ int r = librbd::api::Snapshot<>::is_protected(ictx, snap_name, is_protected);
tracepoint(librbd, snap_is_protected_exit, r, *is_protected ? 1 : 0);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_list_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, &snaps);
- int r = librbd::snap_list(ictx, snaps);
+ int r = librbd::api::Snapshot<>::list(ictx, snaps);
if (r >= 0) {
for (int i = 0, n = snaps.size(); i < n; i++) {
tracepoint(librbd, snap_list_entry, snaps[i].id, snaps[i].size, snaps[i].name.c_str());
tracepoint(librbd, snap_exists_enter, ictx, ictx->name.c_str(),
ictx->snap_name.c_str(), ictx->read_only, snap_name);
bool exists;
- int r = librbd::snap_exists(ictx, cls::rbd::UserSnapshotNamespace(), snap_name, &exists);
+ int r = librbd::api::Snapshot<>::exists(ictx, cls::rbd::UserSnapshotNamespace(), snap_name, &exists);
tracepoint(librbd, snap_exists_exit, r, exists);
if (r < 0) {
// lie to caller since we don't know the real answer yet.
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_exists_enter, ictx, ictx->name.c_str(),
ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_exists(ictx, cls::rbd::UserSnapshotNamespace(), snap_name, exists);
+ int r = librbd::api::Snapshot<>::exists(ictx, cls::rbd::UserSnapshotNamespace(), snap_name, exists);
tracepoint(librbd, snap_exists_exit, r, *exists);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_get_timestamp_enter, ictx, ictx->name.c_str());
- int r = librbd::snap_get_timestamp(ictx, snap_id, timestamp);
+ int r = librbd::api::Snapshot<>::get_timestamp(ictx, snap_id, timestamp);
tracepoint(librbd, snap_get_timestamp_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_get_limit_enter, ictx, ictx->name.c_str());
- int r = librbd::snap_get_limit(ictx, limit);
+ int r = librbd::api::Snapshot<>::get_limit(ictx, limit);
tracepoint(librbd, snap_get_limit_exit, r, *limit);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_remove_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::snap_remove(ictx, snap_name, 0, prog_ctx);
+ int r = librbd::api::Snapshot<>::remove(ictx, snap_name, 0, prog_ctx);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_remove2_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name, flags);
librbd::CProgressContext prog_ctx(cb, cbdata);
- int r = librbd::snap_remove(ictx, snap_name, flags, prog_ctx);
+ int r = librbd::api::Snapshot<>::remove(ictx, snap_name, flags, prog_ctx);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
}
memset(snaps, 0, sizeof(*snaps) * *max_snaps);
- int r = librbd::snap_list(ictx, cpp_snaps);
+ int r = librbd::api::Snapshot<>::list(ictx, cpp_snaps);
if (r == -ENOENT) {
tracepoint(librbd, snap_list_exit, 0, *max_snaps);
return 0;
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_is_protected_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
bool protected_snap;
- int r = librbd::snap_is_protected(ictx, snap_name, &protected_snap);
+ int r = librbd::api::Snapshot<>::is_protected(ictx, snap_name, &protected_snap);
if (r < 0) {
tracepoint(librbd, snap_is_protected_exit, r, *is_protected ? 1 : 0);
return r;
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_get_limit_enter, ictx, ictx->name.c_str());
- int r = librbd::snap_get_limit(ictx, limit);
+ int r = librbd::api::Snapshot<>::get_limit(ictx, limit);
tracepoint(librbd, snap_get_limit_exit, r, *limit);
return r;
}
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_get_timestamp_enter, ictx, ictx->name.c_str());
- int r = librbd::snap_get_timestamp(ictx, snap_id, timestamp);
+ int r = librbd::api::Snapshot<>::get_timestamp(ictx, snap_id, timestamp);
tracepoint(librbd, snap_get_timestamp_exit, r);
return r;
}
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_set_limit_enter, ictx, ictx->name.c_str(), limit);
- int r = librbd::snap_set_limit(ictx, limit);
+ int r = librbd::api::Snapshot<>::set_limit(ictx, limit);
tracepoint(librbd, snap_set_limit_exit, r);
return r;
}