librbd/LibrbdAdminSocketHook.cc
librbd/LibrbdWriteback.cc
librbd/ObjectMap.cc
+ librbd/Operations.cc
librbd/Utils.cc
librbd/exclusive_lock/AcquireRequest.cc
librbd/exclusive_lock/ReleaseRequest.cc
#include "librbd/Journal.h"
#include "librbd/LibrbdAdminSocketHook.h"
#include "librbd/ObjectMap.h"
+#include "librbd/Operations.h"
#include "librbd/operation/ResizeRequest.h"
#include "librbd/Utils.h"
object_cacher(NULL), writeback_handler(NULL), object_set(NULL),
readahead(),
total_bytes_read(0),
- state(new ImageState<>(this)), exclusive_lock(nullptr),
- object_map(nullptr), aio_work_queue(NULL), op_work_queue(NULL)
+ state(new ImageState<>(this)),
+ operations(new Operations<>(*this)),
+ exclusive_lock(nullptr), object_map(nullptr),
+ aio_work_queue(nullptr), op_work_queue(nullptr),
+ asok_hook(nullptr)
{
md_ctx.dup(p);
data_ctx.dup(p);
delete op_work_queue;
delete aio_work_queue;
delete asok_hook;
+ delete operations;
delete state;
}
template <typename> class Journal;
class LibrbdAdminSocketHook;
class ObjectMap;
+ template <typename> class Operations;
namespace operation {
template <typename> class ResizeRequest;
std::list<Context*> async_requests_waiters;
ImageState<ImageCtx> *state;
+ Operations<ImageCtx> *operations;
+
ExclusiveLock<ImageCtx> *exclusive_lock;
ObjectMap *object_map;
- atomic_t async_request_seq;
-
xlist<operation::ResizeRequest<ImageCtx>*> resize_reqs;
AioImageRequestWQ *aio_work_queue;
#include "librbd/ImageState.h"
#include "librbd/internal.h"
#include "librbd/ObjectMap.h"
+#include "librbd/Operations.h"
#include "librbd/TaskFinisher.h"
#include "librbd/Utils.h"
#include "include/encoding.h"
if (new_request) {
ldout(m_image_ctx.cct, 10) << this << " remote flatten request: "
<< payload.async_request_id << dendl;
- librbd::async_flatten(&m_image_ctx, ctx, *prog_ctx);
+ m_image_ctx.operations->flatten(*prog_ctx, ctx);
}
::encode(ResponseMessage(r), ack_ctx->out);
ldout(m_image_ctx.cct, 10) << this << " remote resize request: "
<< payload.async_request_id << " "
<< payload.size << dendl;
- librbd::async_resize(&m_image_ctx, ctx, payload.size, *prog_ctx);
+ m_image_ctx.operations->resize(payload.size, *prog_ctx, ctx);
}
::encode(ResponseMessage(r), ack_ctx->out);
ldout(m_image_ctx.cct, 10) << this << " remote snap_create request: "
<< payload.snap_name << dendl;
- librbd::snap_create_helper(&m_image_ctx, new C_ResponseMessage(ack_ctx),
- payload.snap_name.c_str());
+ m_image_ctx.operations->snap_create(payload.snap_name.c_str(),
+ new C_ResponseMessage(ack_ctx));
return false;
}
return true;
<< payload.snap_id << " to "
<< payload.snap_name << dendl;
- librbd::snap_rename_helper(&m_image_ctx, new C_ResponseMessage(ack_ctx),
- payload.snap_id, payload.snap_name.c_str());
+ m_image_ctx.operations->snap_rename(payload.snap_id,
+ payload.snap_name.c_str(),
+ new C_ResponseMessage(ack_ctx));
return false;
}
return true;
ldout(m_image_ctx.cct, 10) << this << " remote snap_remove request: "
<< payload.snap_name << dendl;
- librbd::snap_remove_helper(&m_image_ctx, new C_ResponseMessage(ack_ctx),
- payload.snap_name.c_str());
+ m_image_ctx.operations->snap_remove(payload.snap_name.c_str(),
+ new C_ResponseMessage(ack_ctx));
return false;
}
return true;
ldout(m_image_ctx.cct, 10) << this << " remote snap_protect request: "
<< payload.snap_name << dendl;
- librbd::snap_protect_helper(&m_image_ctx, new C_ResponseMessage(ack_ctx),
- payload.snap_name.c_str());
+ m_image_ctx.operations->snap_protect(payload.snap_name.c_str(),
+ new C_ResponseMessage(ack_ctx));
return false;
}
return true;
ldout(m_image_ctx.cct, 10) << this << " remote snap_unprotect request: "
<< payload.snap_name << dendl;
- librbd::snap_unprotect_helper(&m_image_ctx, new C_ResponseMessage(ack_ctx),
- payload.snap_name.c_str());
+ m_image_ctx.operations->snap_unprotect(payload.snap_name.c_str(),
+ new C_ResponseMessage(ack_ctx));
return false;
}
return true;
ldout(m_image_ctx.cct, 10) << this
<< " remote rebuild object map request: "
<< payload.async_request_id << dendl;
- librbd::async_rebuild_object_map(&m_image_ctx, ctx, *prog_ctx);
+ m_image_ctx.operations->rebuild_object_map(*prog_ctx, ctx);
}
::encode(ResponseMessage(r), ack_ctx->out);
ldout(m_image_ctx.cct, 10) << this << " remote rename request: "
<< payload.image_name << dendl;
- librbd::rename_helper(&m_image_ctx, new C_ResponseMessage(ack_ctx),
- payload.image_name.c_str());
+ m_image_ctx.operations->rename(payload.image_name.c_str(),
+ new C_ResponseMessage(ack_ctx));
return false;
}
return true;
librbd/LibrbdAdminSocketHook.cc \
librbd/LibrbdWriteback.cc \
librbd/ObjectMap.cc \
+ librbd/Operations.cc \
librbd/Utils.cc \
librbd/exclusive_lock/AcquireRequest.cc \
librbd/exclusive_lock/ReleaseRequest.cc \
librbd/LibrbdAdminSocketHook.h \
librbd/LibrbdWriteback.h \
librbd/ObjectMap.h \
+ librbd/Operations.h \
librbd/parent_types.h \
librbd/SnapInfo.h \
librbd/TaskFinisher.h \
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/Operations.h"
+#include "common/dout.h"
+#include "common/errno.h"
+#include "librbd/ExclusiveLock.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/ImageWatcher.h"
+#include "librbd/operation/FlattenRequest.h"
+#include "librbd/operation/RebuildObjectMapRequest.h"
+#include "librbd/operation/RenameRequest.h"
+#include "librbd/operation/ResizeRequest.h"
+#include "librbd/operation/SnapshotCreateRequest.h"
+#include "librbd/operation/SnapshotProtectRequest.h"
+#include "librbd/operation/SnapshotRemoveRequest.h"
+#include "librbd/operation/SnapshotRenameRequest.h"
+#include "librbd/operation/SnapshotRollbackRequest.h"
+#include "librbd/operation/SnapshotUnprotectRequest.h"
+#include <boost/bind.hpp>
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::Operations: "
+
+namespace librbd {
+
+template <typename I>
+Operations<I>::Operations(I &image_ctx) : m_image_ctx(image_ctx) {
+}
+
+template <typename I>
+int Operations<I>::flatten(ProgressContext &prog_ctx) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 20) << "flatten" << dendl;
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0) {
+ return r;
+ }
+
+ if (m_image_ctx.read_only) {
+ return -EROFS;
+ }
+
+ {
+ RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
+ if (m_image_ctx.parent_md.spec.pool_id == -1) {
+ lderr(cct) << "image has no parent" << dendl;
+ return -EINVAL;
+ }
+ }
+
+ uint64_t request_id = m_async_request_seq.inc();
+ r = invoke_async_request("flatten", false,
+ boost::bind(&Operations<I>::flatten, this,
+ boost::ref(prog_ctx), _1),
+ boost::bind(&ImageWatcher::notify_flatten,
+ m_image_ctx.image_watcher, request_id,
+ boost::ref(prog_ctx)));
+
+ if (r < 0 && r != -EINVAL) {
+ return r;
+ }
+
+ notify_change();
+ ldout(cct, 20) << "flatten finished" << dendl;
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::flatten(ProgressContext &prog_ctx, Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 20) << "flatten" << dendl;
+
+ uint64_t object_size;
+ uint64_t overlap_objects;
+ ::SnapContext snapc;
+
+ {
+ uint64_t overlap;
+ RWLock::RLocker l(m_image_ctx.snap_lock);
+ RWLock::RLocker l2(m_image_ctx.parent_lock);
+
+ if (m_image_ctx.read_only) {
+ on_finish->complete(-EROFS);
+ return;
+ }
+
+ // can't flatten a non-clone
+ if (m_image_ctx.parent_md.spec.pool_id == -1) {
+ lderr(cct) << "image has no parent" << dendl;
+ on_finish->complete(-EINVAL);
+ return;
+ }
+ if (m_image_ctx.snap_id != CEPH_NOSNAP) {
+ lderr(cct) << "snapshots cannot be flattened" << dendl;
+ on_finish->complete(-EROFS);
+ return;
+ }
+
+ snapc = m_image_ctx.snapc;
+ assert(m_image_ctx.parent != NULL);
+ int r = m_image_ctx.get_parent_overlap(CEPH_NOSNAP, &overlap);
+ assert(r == 0);
+ assert(overlap <= m_image_ctx.size);
+
+ object_size = m_image_ctx.get_object_size();
+ overlap_objects = Striper::get_num_objects(m_image_ctx.layout, overlap);
+ }
+
+ operation::FlattenRequest<I> *req = new operation::FlattenRequest<I>(
+ m_image_ctx, on_finish, object_size, overlap_objects, snapc, prog_ctx);
+ req->send();
+}
+
+template <typename I>
+int Operations<I>::rebuild_object_map(ProgressContext &prog_ctx) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 10) << "rebuild_object_map" << dendl;
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0) {
+ return r;
+ }
+
+ uint64_t request_id = m_async_request_seq.inc();
+ r = invoke_async_request("rebuild object map", true,
+ boost::bind(&Operations<I>::rebuild_object_map, this,
+ boost::ref(prog_ctx), _1),
+ boost::bind(&ImageWatcher::notify_rebuild_object_map,
+ m_image_ctx.image_watcher, request_id,
+ boost::ref(prog_ctx)));
+
+ ldout(cct, 10) << "rebuild object map finished" << dendl;
+ if (r < 0) {
+ return r;
+ }
+
+ notify_change();
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::rebuild_object_map(ProgressContext &prog_ctx,
+ Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << dendl;
+
+ if (m_image_ctx.read_only) {
+ on_finish->complete(-EROFS);
+ return;
+ }
+ if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP)) {
+ on_finish->complete(-EINVAL);
+ return;
+ }
+
+ operation::RebuildObjectMapRequest<I> *req =
+ new operation::RebuildObjectMapRequest<I>(m_image_ctx, on_finish, prog_ctx);
+ req->send();
+}
+
+template <typename I>
+int Operations<I>::rename(const char *dstname) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": dest_name=" << dstname
+ << dendl;
+
+ int r = librbd::detect_format(m_image_ctx.md_ctx, dstname, NULL, NULL);
+ if (r < 0 && r != -ENOENT) {
+ lderr(cct) << "error checking for existing image called "
+ << dstname << ":" << cpp_strerror(r) << dendl;
+ return r;
+ }
+ if (r == 0) {
+ lderr(cct) << "rbd image " << dstname << " already exists" << dendl;
+ return -EEXIST;
+ }
+
+ if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+ r = invoke_async_request("rename", true,
+ boost::bind(&Operations<I>::rename, this,
+ dstname, _1),
+ boost::bind(&ImageWatcher::notify_rename,
+ m_image_ctx.image_watcher, dstname));
+ if (r < 0 && r != -EEXIST) {
+ return r;
+ }
+ } else {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ C_SaferCond cond_ctx;
+ rename(dstname, &cond_ctx);
+
+ r = cond_ctx.wait();
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ if (m_image_ctx.old_format) {
+ notify_change();
+ }
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::rename(const char *dstname, Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+ }
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": dest_name=" << dstname
+ << dendl;
+
+ operation::RenameRequest<I> *req =
+ new operation::RenameRequest<I>(m_image_ctx, on_finish, dstname);
+ req->send();
+}
+
+template <typename I>
+int Operations<I>::resize(uint64_t size, ProgressContext& prog_ctx) {
+ CephContext *cct = m_image_ctx.cct;
+
+ m_image_ctx.snap_lock.get_read();
+ ldout(cct, 5) << this << " " << __func__ << ": "
+ << "size=" << m_image_ctx.size << ", "
+ << "new_size=" << size << dendl;
+ m_image_ctx.snap_lock.put_read();
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0) {
+ return r;
+ }
+
+ uint64_t request_id = m_async_request_seq.inc();
+ r = invoke_async_request("resize", false,
+ boost::bind(&Operations<I>::resize, this,
+ size, boost::ref(prog_ctx), _1),
+ boost::bind(&ImageWatcher::notify_resize,
+ m_image_ctx.image_watcher, request_id,
+ size, boost::ref(prog_ctx)));
+
+ m_image_ctx.perfcounter->inc(l_librbd_resize);
+ notify_change();
+ ldout(cct, 2) << "resize finished" << dendl;
+ return r;
+}
+
+template <typename I>
+void Operations<I>::resize(uint64_t size, ProgressContext &prog_ctx,
+ Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+
+ CephContext *cct = m_image_ctx.cct;
+ m_image_ctx.snap_lock.get_read();
+ ldout(cct, 5) << this << " " << __func__ << ": "
+ << "size=" << m_image_ctx.size << ", "
+ << "new_size=" << size << dendl;
+ m_image_ctx.snap_lock.put_read();
+
+ {
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ if (m_image_ctx.snap_id != CEPH_NOSNAP || m_image_ctx.read_only) {
+ on_finish->complete(-EROFS);
+ return;
+ }
+ }
+
+ operation::ResizeRequest<I> *req = new operation::ResizeRequest<I>(
+ m_image_ctx, on_finish, size, prog_ctx);
+ req->send();
+}
+
+template <typename I>
+int Operations<I>::snap_create(const char *snap_name) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ if (m_image_ctx.read_only) {
+ return -EROFS;
+ }
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ {
+ RWLock::RLocker l(m_image_ctx.snap_lock);
+ if (m_image_ctx.get_snap_id(snap_name) != CEPH_NOSNAP) {
+ return -EEXIST;
+ }
+ }
+
+ r = invoke_async_request("snap_create", true,
+ boost::bind(&Operations<I>::snap_create, this,
+ snap_name, _1),
+ boost::bind(&ImageWatcher::notify_snap_create,
+ m_image_ctx.image_watcher, snap_name));
+ if (r < 0 && r != -EEXIST) {
+ return r;
+ }
+
+ m_image_ctx.perfcounter->inc(l_librbd_snap_create);
+ notify_change();
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::snap_create(const char *snap_name, Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ operation::SnapshotCreateRequest<I> *req =
+ new operation::SnapshotCreateRequest<I>(m_image_ctx, on_finish, snap_name);
+ req->send();
+}
+
+template <typename I>
+int Operations<I>::snap_rollback(const char *snap_name,
+ ProgressContext& prog_ctx) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+ {
+ // need to drop snap_lock before invalidating cache
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ if (!m_image_ctx.snap_exists) {
+ return -ENOENT;
+ }
+
+ if (m_image_ctx.snap_id != CEPH_NOSNAP || m_image_ctx.read_only) {
+ return -EROFS;
+ }
+
+ uint64_t snap_id = m_image_ctx.get_snap_id(snap_name);
+ if (snap_id == CEPH_NOSNAP) {
+ lderr(cct) << "No such snapshot found." << dendl;
+ return -ENOENT;
+ }
+ }
+
+ r = prepare_image_update();
+ if (r < 0) {
+ return -EROFS;
+ }
+ if (m_image_ctx.exclusive_lock != nullptr &&
+ !m_image_ctx.exclusive_lock->is_lock_owner()) {
+ return -EROFS;
+ }
+
+ C_SaferCond cond_ctx;
+ snap_rollback(snap_name, prog_ctx, &cond_ctx);
+ r = cond_ctx.wait();
+ if (r < 0) {
+ return r;
+ }
+
+ m_image_ctx.perfcounter->inc(l_librbd_snap_rollback);
+ notify_change();
+ return r;
+}
+
+template <typename I>
+void Operations<I>::snap_rollback(const char *snap_name,
+ ProgressContext& prog_ctx,
+ Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ uint64_t snap_id;
+ uint64_t new_size;
+ {
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ snap_id = m_image_ctx.get_snap_id(snap_name);
+ if (snap_id == CEPH_NOSNAP) {
+ lderr(cct) << "No such snapshot found." << dendl;
+ on_finish->complete(-ENOENT);
+ return;
+ }
+
+ new_size = m_image_ctx.get_image_size(snap_id);
+ }
+
+ // async mode used for journal replay
+ operation::SnapshotRollbackRequest<I> *request =
+ new operation::SnapshotRollbackRequest<I>(m_image_ctx, on_finish, snap_name,
+ snap_id, new_size, prog_ctx);
+ request->send();
+}
+
+template <typename I>
+int Operations<I>::snap_remove(const char *snap_name) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ if (m_image_ctx.read_only)
+ return -EROFS;
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ bool proxy_op = false;
+ {
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ if (m_image_ctx.get_snap_id(snap_name) == CEPH_NOSNAP) {
+ return -ENOENT;
+ }
+ proxy_op = ((m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0 ||
+ (m_image_ctx.features & RBD_FEATURE_JOURNALING) != 0);
+ }
+
+ if (proxy_op) {
+ r = invoke_async_request("snap_remove", true,
+ boost::bind(&Operations<I>::snap_remove, this,
+ snap_name, _1),
+ boost::bind(&ImageWatcher::notify_snap_remove,
+ m_image_ctx.image_watcher, snap_name));
+ if (r < 0 && r != -ENOENT) {
+ return r;
+ }
+ } else {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ C_SaferCond cond_ctx;
+ snap_remove(snap_name, &cond_ctx);
+
+ r = cond_ctx.wait();
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ m_image_ctx.perfcounter->inc(l_librbd_snap_remove);
+ notify_change();
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::snap_remove(const char *snap_name, Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ {
+ if ((m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0) {
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+ }
+ }
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ uint64_t snap_id;
+ {
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ snap_id = m_image_ctx.get_snap_id(snap_name);
+ if (snap_id == CEPH_NOSNAP) {
+ lderr(m_image_ctx.cct) << "No such snapshot found." << dendl;
+ on_finish->complete(-ENOENT);
+ return;
+ }
+
+ bool is_protected;
+ int r = m_image_ctx.is_snap_protected(snap_id, &is_protected);
+ if (r < 0) {
+ on_finish->complete(r);
+ return;
+ } else if (is_protected) {
+ lderr(m_image_ctx.cct) << "snapshot is protected" << dendl;
+ on_finish->complete(-EBUSY);
+ return;
+ }
+ }
+
+ operation::SnapshotRemoveRequest<I> *req =
+ new operation::SnapshotRemoveRequest<I>(m_image_ctx, on_finish, snap_name,
+ snap_id);
+ req->send();
+}
+
+template <typename I>
+int Operations<I>::snap_rename(const char *srcname, const char *dstname) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": "
+ << "snap_name=" << srcname << ", "
+ << "new_snap_name=" << dstname << dendl;
+
+ snapid_t snap_id;
+ if (m_image_ctx.read_only) {
+ return -EROFS;
+ }
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0)
+ return r;
+
+ {
+ RWLock::RLocker l(m_image_ctx.snap_lock);
+ snap_id = m_image_ctx.get_snap_id(srcname);
+ if (snap_id == CEPH_NOSNAP) {
+ return -ENOENT;
+ }
+ if (m_image_ctx.get_snap_id(dstname) != CEPH_NOSNAP) {
+ return -EEXIST;
+ }
+ }
+
+ if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+ r = invoke_async_request("snap_rename", true,
+ boost::bind(&Operations<I>::snap_rename, this,
+ snap_id, dstname, _1),
+ boost::bind(&ImageWatcher::notify_snap_rename,
+ m_image_ctx.image_watcher, snap_id,
+ dstname));
+ if (r < 0 && r != -EEXIST) {
+ return r;
+ }
+ } else {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ C_SaferCond cond_ctx;
+ snap_rename(snap_id, dstname, &cond_ctx);
+
+ r = cond_ctx.wait();
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ m_image_ctx.perfcounter->inc(l_librbd_snap_rename);
+ notify_change();
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::snap_rename(const uint64_t src_snap_id,
+ const char *dst_name, Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ if ((m_image_ctx.features & RBD_FEATURE_JOURNALING) != 0) {
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+ }
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": "
+ << "snap_id=" << src_snap_id << ", "
+ << "new_snap_name=" << dst_name << dendl;
+
+ operation::SnapshotRenameRequest<I> *req =
+ new operation::SnapshotRenameRequest<I>(m_image_ctx, on_finish, src_snap_id,
+ dst_name);
+ req->send();
+}
+
+template <typename I>
+int Operations<I>::snap_protect(const char *snap_name) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ if (m_image_ctx.read_only) {
+ return -EROFS;
+ }
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0) {
+ return r;
+ }
+
+ {
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ bool is_protected;
+ r = m_image_ctx.is_snap_protected(m_image_ctx.get_snap_id(snap_name),
+ &is_protected);
+ if (r < 0) {
+ return r;
+ }
+
+ if (is_protected) {
+ return -EBUSY;
+ }
+ }
+
+ if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+ r = invoke_async_request("snap_protect", true,
+ boost::bind(&Operations<I>::snap_protect, this,
+ snap_name, _1),
+ boost::bind(&ImageWatcher::notify_snap_protect,
+ m_image_ctx.image_watcher, snap_name));
+ if (r < 0 && r != -EBUSY) {
+ return r;
+ }
+ } else {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ C_SaferCond cond_ctx;
+ snap_protect(snap_name, &cond_ctx);
+
+ r = cond_ctx.wait();
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ notify_change();
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::snap_protect(const char *snap_name, Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+ }
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ operation::SnapshotProtectRequest<I> *request =
+ new operation::SnapshotProtectRequest<I>(m_image_ctx, on_finish, snap_name);
+ request->send();
+}
+
+template <typename I>
+int Operations<I>::snap_unprotect(const char *snap_name) {
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ if (m_image_ctx.read_only) {
+ return -EROFS;
+ }
+
+ int r = m_image_ctx.state->refresh_if_required();
+ if (r < 0) {
+ return r;
+ }
+
+ {
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ bool is_unprotected;
+ r = m_image_ctx.is_snap_unprotected(m_image_ctx.get_snap_id(snap_name),
+ &is_unprotected);
+ if (r < 0) {
+ return r;
+ }
+
+ if (is_unprotected) {
+ return -EINVAL;
+ }
+ }
+
+ if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+ r = invoke_async_request("snap_unprotect", true,
+ boost::bind(&Operations<I>::snap_unprotect, this,
+ snap_name, _1),
+ boost::bind(&ImageWatcher::notify_snap_unprotect,
+ m_image_ctx.image_watcher, snap_name));
+ if (r < 0 && r != -EINVAL) {
+ return r;
+ }
+ } else {
+ RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+ C_SaferCond cond_ctx;
+ snap_unprotect(snap_name, &cond_ctx);
+
+ r = cond_ctx.wait();
+ if (r < 0) {
+ return r;
+ }
+ }
+
+ notify_change();
+ return 0;
+}
+
+template <typename I>
+void Operations<I>::snap_unprotect(const char *snap_name, Context *on_finish) {
+ assert(m_image_ctx.owner_lock.is_locked());
+ if (m_image_ctx.test_features(RBD_FEATURE_JOURNALING)) {
+ assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+ }
+
+ CephContext *cct = m_image_ctx.cct;
+ ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
+ << dendl;
+
+ operation::SnapshotUnprotectRequest<I> *request =
+ new operation::SnapshotUnprotectRequest<I>(m_image_ctx, on_finish,
+ snap_name);
+ request->send();
+}
+
+template <typename I>
+int Operations<I>::prepare_image_update() {
+ assert(m_image_ctx.owner_lock.is_locked() &&
+ !m_image_ctx.owner_lock.is_wlocked());
+ if (m_image_ctx.image_watcher == NULL) {
+ return -EROFS;
+ }
+
+ // need to upgrade to a write lock
+ int r = 0;
+ bool trying_lock = false;
+ C_SaferCond ctx;
+ m_image_ctx.owner_lock.put_read();
+ {
+ RWLock::WLocker owner_locker(m_image_ctx.owner_lock);
+ if (m_image_ctx.exclusive_lock != nullptr &&
+ !m_image_ctx.exclusive_lock->is_lock_owner()) {
+ m_image_ctx.exclusive_lock->try_lock(&ctx);
+ trying_lock = true;
+ }
+ }
+
+ if (trying_lock) {
+ r = ctx.wait();
+ }
+ m_image_ctx.owner_lock.get_read();
+
+ return r;
+}
+
+template <typename I>
+int Operations<I>::invoke_async_request(const std::string& request_type,
+ bool permit_snapshot,
+ const boost::function<void(Context*)>& local_request,
+ const boost::function<int()>& remote_request) {
+ CephContext *cct = m_image_ctx.cct;
+ int r;
+ do {
+ C_SaferCond ctx;
+ {
+ RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+ {
+ RWLock::RLocker snap_locker(m_image_ctx.snap_lock);
+ if (m_image_ctx.read_only ||
+ (!permit_snapshot && m_image_ctx.snap_id != CEPH_NOSNAP)) {
+ return -EROFS;
+ }
+ }
+
+ while (m_image_ctx.exclusive_lock != nullptr) {
+ r = prepare_image_update();
+ if (r < 0) {
+ return -EROFS;
+ } else if (m_image_ctx.exclusive_lock->is_lock_owner()) {
+ break;
+ }
+
+ r = remote_request();
+ if (r != -ETIMEDOUT && r != -ERESTART) {
+ return r;
+ }
+ ldout(cct, 5) << request_type << " timed out notifying lock owner"
+ << dendl;
+ }
+
+ local_request(&ctx);
+ }
+
+ r = ctx.wait();
+ if (r == -ERESTART) {
+ ldout(cct, 5) << request_type << " interrupted: restarting" << dendl;
+ }
+ } while (r == -ERESTART);
+ return r;
+}
+
+template <typename I>
+void Operations<I>::notify_change() {
+ m_image_ctx.state->handle_update_notification();
+ ImageWatcher::notify_header_update(m_image_ctx.md_ctx,
+ m_image_ctx.header_oid);
+}
+
+} // namespace librbd
+
+template class librbd::Operations<librbd::ImageCtx>;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_OPERATIONS_H
+#define CEPH_LIBRBD_OPERATIONS_H
+
+#include "include/int_types.h"
+#include "include/atomic.h"
+#include <string>
+#include <boost/function.hpp>
+
+class Context;
+
+namespace librbd {
+
+class ImageCtx;
+class ProgressContext;
+
+template <typename ImageCtxT = ImageCtx>
+class Operations {
+public:
+ Operations(ImageCtxT &image_ctx);
+
+ int flatten(ProgressContext &prog_ctx);
+ void flatten(ProgressContext &prog_ctx, Context *on_finish);
+
+ int rebuild_object_map(ProgressContext &prog_ctx);
+ void rebuild_object_map(ProgressContext &prog_ctx, Context *on_finish);
+
+ int rename(const char *dstname);
+ void rename(const char *dstname, Context *on_finish);
+
+ int resize(uint64_t size, ProgressContext& prog_ctx);
+ void resize(uint64_t size, ProgressContext &prog_ctx, Context *on_finish);
+
+ int snap_create(const char *snap_name);
+ void snap_create(const char *snap_name, Context *on_finish);
+
+ int snap_rollback(const char *snap_name, ProgressContext& prog_ctx);
+ void snap_rollback(const char *snap_name, ProgressContext& prog_ctx,
+ Context *on_finish);
+
+ int snap_remove(const char *snap_name);
+ void snap_remove(const char *snap_name, Context *on_finish);
+
+ int snap_rename(const char *srcname, const char *dstname);
+ void snap_rename(const uint64_t src_snap_id, const char *dst_name,
+ Context *on_finish);
+
+ int snap_protect(const char *snap_name);
+ void snap_protect(const char *snap_name, Context *on_finish);
+
+ int snap_unprotect(const char *snap_name);
+ void snap_unprotect(const char *snap_name, Context *on_finish);
+
+ int prepare_image_update();
+
+private:
+ ImageCtxT &m_image_ctx;
+ atomic_t m_async_request_seq;
+
+ int invoke_async_request(const std::string& request_type,
+ bool permit_snapshot,
+ const boost::function<void(Context*)>& local_request,
+ const boost::function<int()>& remote_request);
+ void notify_change();
+};
+
+} // namespace librbd
+
+extern template class librbd::Operations<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_OPERATIONS_H
#include "librbd/internal.h"
#include "librbd/Journal.h"
#include "librbd/ObjectMap.h"
+#include "librbd/Operations.h"
#include "librbd/parent_types.h"
#include "librbd/Utils.h"
-#include "librbd/operation/FlattenRequest.h"
-#include "librbd/operation/RebuildObjectMapRequest.h"
-#include "librbd/operation/RenameRequest.h"
-#include "librbd/operation/ResizeRequest.h"
-#include "librbd/operation/SnapshotCreateRequest.h"
-#include "librbd/operation/SnapshotProtectRequest.h"
-#include "librbd/operation/SnapshotRemoveRequest.h"
-#include "librbd/operation/SnapshotRenameRequest.h"
-#include "librbd/operation/SnapshotRollbackRequest.h"
-#include "librbd/operation/SnapshotUnprotectRequest.h"
#include "librbd/operation/TrimRequest.h"
#include "include/util.h"
return 0;
}
-
int update_all_flags(ImageCtx *ictx, uint64_t flags, uint64_t mask) {
assert(ictx->snap_lock.is_locked());
CephContext *cct = ictx->cct;
return 0;
}
-int prepare_image_update(ImageCtx *ictx) {
- assert(ictx->owner_lock.is_locked() && !ictx->owner_lock.is_wlocked());
- if (ictx->image_watcher == NULL) {
- return -EROFS;
- }
-
- // need to upgrade to a write lock
- int r = 0;
- bool trying_lock = false;
- C_SaferCond ctx;
- ictx->owner_lock.put_read();
- {
- RWLock::WLocker owner_locker(ictx->owner_lock);
- if (ictx->exclusive_lock != nullptr &&
- !ictx->exclusive_lock->is_lock_owner()) {
- ictx->exclusive_lock->try_lock(&ctx);
- trying_lock = true;
- }
- }
-
- if (trying_lock) {
- r = ctx.wait();
- }
- ictx->owner_lock.get_read();
-
- return r;
-}
-
-int invoke_async_request(ImageCtx *ictx, const std::string& request_type,
- bool permit_snapshot,
- const boost::function<void(Context*)>& local_request,
- const boost::function<int()>& remote_request) {
- int r;
- do {
- C_SaferCond ctx;
- {
- RWLock::RLocker l(ictx->owner_lock);
- {
- RWLock::RLocker snap_locker(ictx->snap_lock);
- if (ictx->read_only ||
- (!permit_snapshot && ictx->snap_id != CEPH_NOSNAP)) {
- return -EROFS;
- }
- }
-
- while (ictx->exclusive_lock != nullptr) {
- r = prepare_image_update(ictx);
- if (r < 0) {
- return -EROFS;
- } else if (ictx->exclusive_lock->is_lock_owner()) {
- break;
- }
-
- r = remote_request();
- if (r != -ETIMEDOUT && r != -ERESTART) {
- return r;
- }
- ldout(ictx->cct, 5) << request_type << " timed out notifying lock owner"
- << dendl;
- }
-
- local_request(&ctx);
- }
-
- r = ctx.wait();
- if (r == -ERESTART) {
- ldout(ictx->cct, 5) << request_type << " interrupted: restarting"
- << dendl;
- }
- } while (r == -ERESTART);
- return r;
-}
-
int validate_pool(IoCtx &io_ctx, CephContext *cct) {
if (!cct->_conf->rbd_validate_pool) {
return 0;
return 0;
}
- int snap_create(ImageCtx *ictx, const char *snap_name)
- {
- ldout(ictx->cct, 20) << "snap_create " << ictx << " " << snap_name << dendl;
-
- if (ictx->read_only) {
- return -EROFS;
- }
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- {
- RWLock::RLocker l(ictx->snap_lock);
- if (ictx->get_snap_id(snap_name) != CEPH_NOSNAP) {
- return -EEXIST;
- }
- }
-
- r = invoke_async_request(ictx, "snap_create", true,
- boost::bind(&snap_create_helper, ictx, _1,
- snap_name),
- boost::bind(&ImageWatcher::notify_snap_create,
- ictx->image_watcher, snap_name));
- if (r < 0 && r != -EEXIST) {
- return r;
- }
-
- ictx->perfcounter->inc(l_librbd_snap_create);
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- return 0;
- }
-
- void snap_create_helper(ImageCtx* ictx, Context* ctx, const char* snap_name) {
- assert(ictx->owner_lock.is_locked());
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
-
- ldout(ictx->cct, 20) << "snap_create_helper " << ictx << " " << snap_name
- << dendl;
-
- operation::SnapshotCreateRequest<> *req =
- new operation::SnapshotCreateRequest<>(*ictx, ctx, snap_name);
- req->send();
- }
-
- int snap_remove(ImageCtx *ictx, const char *snap_name)
- {
- ldout(ictx->cct, 20) << "snap_remove " << ictx << " " << snap_name << dendl;
-
- if (ictx->read_only)
- return -EROFS;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- bool proxy_op = false;
- {
- RWLock::RLocker snap_locker(ictx->snap_lock);
- if (ictx->get_snap_id(snap_name) == CEPH_NOSNAP) {
- return -ENOENT;
- }
- proxy_op = ((ictx->features & RBD_FEATURE_FAST_DIFF) != 0 ||
- (ictx->features & RBD_FEATURE_JOURNALING) != 0);
- }
-
- if (proxy_op) {
- r = invoke_async_request(ictx, "snap_remove", true,
- boost::bind(&snap_remove_helper, ictx, _1,
- snap_name),
- boost::bind(&ImageWatcher::notify_snap_remove,
- ictx->image_watcher, snap_name));
- if (r < 0 && r != -ENOENT) {
- return r;
- }
- } else {
- RWLock::RLocker owner_lock(ictx->owner_lock);
- C_SaferCond cond_ctx;
- snap_remove_helper(ictx, &cond_ctx, snap_name);
-
- r = cond_ctx.wait();
- if (r < 0) {
- return r;
- }
- }
-
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
-
- ictx->perfcounter->inc(l_librbd_snap_remove);
- return 0;
- }
-
- void snap_remove_helper(ImageCtx *ictx, Context *ctx, const char *snap_name)
- {
- assert(ictx->owner_lock.is_locked());
- {
- if ((ictx->features & RBD_FEATURE_FAST_DIFF) != 0) {
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
- }
- }
-
- ldout(ictx->cct, 20) << "snap_remove_helper " << ictx << " " << snap_name
- << dendl;
-
- uint64_t snap_id;
- {
- RWLock::RLocker snap_locker(ictx->snap_lock);
- snap_id = ictx->get_snap_id(snap_name);
- if (snap_id == CEPH_NOSNAP) {
- lderr(ictx->cct) << "No such snapshot found." << dendl;
- ctx->complete(-ENOENT);
- return;
- }
-
- bool is_protected;
- int r = ictx->is_snap_protected(snap_id, &is_protected);
- if (r < 0) {
- ctx->complete(r);
- return;
- } else if (is_protected) {
- lderr(ictx->cct) << "snapshot is protected" << dendl;
- ctx->complete(-EBUSY);
- return;
- }
- }
-
- operation::SnapshotRemoveRequest<> *req =
- new operation::SnapshotRemoveRequest<>(*ictx, ctx, snap_name, snap_id);
- req->send();
- }
-
- int snap_rename(ImageCtx *ictx, const char *srcname, const char *dstname)
- {
- ldout(ictx->cct, 20) << "snap_rename " << ictx << " from " << srcname << " to " << dstname << dendl;
-
- snapid_t snap_id;
- if (ictx->read_only) {
- return -EROFS;
- }
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- {
- RWLock::RLocker l(ictx->snap_lock);
- snap_id = ictx->get_snap_id(srcname);
- if (snap_id == CEPH_NOSNAP) {
- return -ENOENT;
- }
- if (ictx->get_snap_id(dstname) != CEPH_NOSNAP) {
- return -EEXIST;
- }
- }
-
- if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
- r = invoke_async_request(ictx, "snap_rename", true,
- boost::bind(&snap_rename_helper, ictx, _1,
- snap_id, dstname),
- boost::bind(&ImageWatcher::notify_snap_rename,
- ictx->image_watcher, snap_id,
- dstname));
- if (r < 0 && r != -EEXIST) {
- return r;
- }
- } else {
- RWLock::RLocker owner_lock(ictx->owner_lock);
- C_SaferCond cond_ctx;
- snap_rename_helper(ictx, &cond_ctx, snap_id, dstname);
-
- r = cond_ctx.wait();
- if (r < 0) {
- return r;
- }
- }
-
- ictx->perfcounter->inc(l_librbd_snap_rename);
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- return 0;
- }
-
- void snap_rename_helper(ImageCtx* ictx, Context* ctx,
- const uint64_t src_snap_id, const char* dst_name) {
- assert(ictx->owner_lock.is_locked());
- if ((ictx->features & RBD_FEATURE_JOURNALING) != 0) {
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
- }
- ldout(ictx->cct, 20) << __func__ << " " << ictx << " from "
- << src_snap_id << " to " << dst_name << dendl;
-
- operation::SnapshotRenameRequest<> *req =
- new operation::SnapshotRenameRequest<>(*ictx, ctx, src_snap_id, dst_name);
- req->send();
- }
-
- int snap_protect(ImageCtx *ictx, const char *snap_name)
- {
- ldout(ictx->cct, 20) << "snap_protect " << ictx << " " << snap_name
- << dendl;
-
- if (ictx->read_only) {
- return -EROFS;
- }
-
- int r = ictx->state->refresh_if_required();
- if (r < 0) {
- return r;
- }
-
- {
- RWLock::RLocker snap_locker(ictx->snap_lock);
- bool is_protected;
- r = ictx->is_snap_protected(ictx->get_snap_id(snap_name), &is_protected);
- if (r < 0) {
- return r;
- }
-
- if (is_protected) {
- return -EBUSY;
- }
- }
-
- if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
- r = invoke_async_request(ictx, "snap_protect", true,
- boost::bind(&snap_protect_helper, ictx, _1,
- snap_name),
- boost::bind(&ImageWatcher::notify_snap_protect,
- ictx->image_watcher, snap_name));
- if (r < 0 && r != -EBUSY) {
- return r;
- }
- } else {
- RWLock::RLocker owner_lock(ictx->owner_lock);
- C_SaferCond cond_ctx;
- snap_protect_helper(ictx, &cond_ctx, snap_name);
-
- r = cond_ctx.wait();
- if (r < 0) {
- return r;
- }
- }
-
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- return 0;
- }
-
- void snap_protect_helper(ImageCtx *ictx, Context* ctx, const char *snap_name)
- {
- assert(ictx->owner_lock.is_locked());
- if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
- }
-
- ldout(ictx->cct, 20) << "snap_protect_helper " << ictx << " " << snap_name
- << dendl;
-
- operation::SnapshotProtectRequest<> *request =
- new operation::SnapshotProtectRequest<>(*ictx, ctx, snap_name);
- request->send();
- }
-
- int snap_unprotect(ImageCtx *ictx, const char *snap_name)
- {
- ldout(ictx->cct, 20) << "snap_unprotect " << ictx << " " << snap_name
- << dendl;
-
- if (ictx->read_only) {
- return -EROFS;
- }
-
- int r = ictx->state->refresh_if_required();
- if (r < 0) {
- return r;
- }
-
- {
- RWLock::RLocker snap_locker(ictx->snap_lock);
- bool is_unprotected;
- r = ictx->is_snap_unprotected(ictx->get_snap_id(snap_name),
- &is_unprotected);
- if (r < 0) {
- return r;
- }
-
- if (is_unprotected) {
- return -EINVAL;
- }
- }
-
- if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
- r = invoke_async_request(ictx, "snap_unprotect", true,
- boost::bind(&snap_unprotect_helper, ictx, _1,
- snap_name),
- boost::bind(&ImageWatcher::notify_snap_unprotect,
- ictx->image_watcher, snap_name));
- if (r < 0 && r != -EINVAL) {
- return r;
- }
- } else {
- RWLock::RLocker owner_lock(ictx->owner_lock);
- C_SaferCond cond_ctx;
- snap_unprotect_helper(ictx, &cond_ctx, snap_name);
-
- r = cond_ctx.wait();
- if (r < 0) {
- return r;
- }
- }
-
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- return 0;
- }
-
- void snap_unprotect_helper(ImageCtx *ictx, Context* ctx,
- const char *snap_name)
- {
- assert(ictx->owner_lock.is_locked());
- if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
- }
-
- ldout(ictx->cct, 20) << "snap_unprotect_helper " << ictx << " " << snap_name
- << dendl;
-
- operation::SnapshotUnprotectRequest<> *request =
- new operation::SnapshotUnprotectRequest<>(*ictx, ctx, snap_name);
- request->send();
- }
-
int snap_is_protected(ImageCtx *ictx, const char *snap_name,
bool *is_protected)
{
ictx->state->close();
} BOOST_SCOPE_EXIT_END
- r = detect_format(io_ctx, dstname, NULL, NULL);
- if (r < 0 && r != -ENOENT) {
- lderr(cct) << "error checking for existing image called "
- << dstname << ":" << cpp_strerror(r) << dendl;
- return r;
- }
- if (r == 0) {
- lderr(cct) << "rbd image " << dstname << " already exists" << dendl;
- return -EEXIST;
- }
-
- if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
- r = invoke_async_request(ictx, "rename", true,
- boost::bind(&rename_helper, ictx, _1,
- dstname),
- boost::bind(&ImageWatcher::notify_rename,
- ictx->image_watcher, dstname));
- if (r < 0 && r != -EEXIST) {
- return r;
- }
- } else {
- RWLock::RLocker owner_lock(ictx->owner_lock);
- C_SaferCond cond_ctx;
- rename_helper(ictx, &cond_ctx, dstname);
-
- r = cond_ctx.wait();
- if (r < 0) {
- return r;
- }
- }
-
- if (ictx->old_format) {
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- }
- return 0;
- }
-
- void rename_helper(ImageCtx *ictx, Context *ctx, const char *dstname)
- {
- assert(ictx->owner_lock.is_locked());
- if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
- }
-
- ldout(ictx->cct, 20) << "rename_helper " << ictx << " " << dstname
- << dendl;
-
- operation::RenameRequest<> *req =
- new operation::RenameRequest<>(*ictx, ctx, dstname);
- req->send();
+ return ictx->operations->rename(dstname);
}
int info(ImageCtx *ictx, image_info_t& info, size_t infosize)
ictx->owner_lock.get_read();
if (ictx->exclusive_lock != nullptr) {
- r = prepare_image_update(ictx);
+ r = ictx->operations->prepare_image_update();
if (r < 0 || !ictx->exclusive_lock->is_lock_owner()) {
lderr(cct) << "cannot obtain exclusive lock - not removing" << dendl;
ictx->owner_lock.put_read();
return 0;
}
- int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx)
- {
- CephContext *cct = ictx->cct;
-
- ictx->snap_lock.get_read();
- ldout(cct, 20) << "resize " << ictx << " " << ictx->size << " -> "
- << size << dendl;
- ictx->snap_lock.put_read();
-
- int r = ictx->state->refresh_if_required();
- if (r < 0) {
- return r;
- }
-
- uint64_t request_id = ictx->async_request_seq.inc();
- r = invoke_async_request(ictx, "resize", false,
- boost::bind(&async_resize, ictx, _1, size,
- boost::ref(prog_ctx)),
- boost::bind(&ImageWatcher::notify_resize,
- ictx->image_watcher, request_id, size,
- boost::ref(prog_ctx)));
-
- ictx->perfcounter->inc(l_librbd_resize);
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- ldout(cct, 2) << "resize finished" << dendl;
- return r;
- }
-
- void async_resize(ImageCtx *ictx, Context *ctx, uint64_t size,
- ProgressContext &prog_ctx)
- {
- assert(ictx->owner_lock.is_locked());
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
-
- CephContext *cct = ictx->cct;
- ictx->snap_lock.get_read();
- ldout(cct, 20) << "async_resize " << ictx << " " << ictx->size << " -> "
- << size << dendl;
- ictx->snap_lock.put_read();
-
- {
- RWLock::RLocker snap_locker(ictx->snap_lock);
- if (ictx->snap_id != CEPH_NOSNAP || ictx->read_only) {
- ctx->complete(-EROFS);
- return;
- }
- }
-
- operation::ResizeRequest<> *req = new operation::ResizeRequest<>(
- *ictx, ctx, size, prog_ctx);
- req->send();
- }
-
int snap_list(ImageCtx *ictx, vector<snap_info_t>& snaps)
{
ldout(ictx->cct, 20) << "snap_list " << ictx << dendl;
return 0;
}
- int snap_rollback(ImageCtx *ictx, const char *snap_name,
- ProgressContext& prog_ctx)
- {
- CephContext *cct = ictx->cct;
- ldout(cct, 20) << "snap_rollback " << ictx << " snap = " << snap_name
- << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0)
- return r;
-
- RWLock::RLocker owner_locker(ictx->owner_lock);
- snap_t snap_id;
- uint64_t new_size;
- {
- {
- // need to drop snap_lock before invalidating cache
- RWLock::RLocker snap_locker(ictx->snap_lock);
- if (!ictx->snap_exists) {
- return -ENOENT;
- }
-
- if (ictx->snap_id != CEPH_NOSNAP || ictx->read_only) {
- return -EROFS;
- }
-
- snap_id = ictx->get_snap_id(snap_name);
- if (snap_id == CEPH_NOSNAP) {
- lderr(cct) << "No such snapshot found." << dendl;
- return -ENOENT;
- }
- }
-
- r = prepare_image_update(ictx);
- if (r < 0) {
- return -EROFS;
- }
- if (ictx->exclusive_lock != nullptr &&
- !ictx->exclusive_lock->is_lock_owner()) {
- return -EROFS;
- }
-
- ictx->snap_lock.get_read();
- if (ictx->journal != NULL) {
- C_SaferCond journal_ctx;
- ictx->journal->wait_for_journal_ready(&journal_ctx);
-
- ictx->snap_lock.put_read();
- r = journal_ctx.wait();
- if (r < 0) {
- lderr(cct) << "Failed to initialize journal: " << cpp_strerror(r)
- << dendl;
- return r;
- }
-
- ictx->snap_lock.get_read();
- }
-
- new_size = ictx->get_image_size(snap_id);
- ictx->snap_lock.put_read();
- }
-
- // TODO need to wait for journal replay to complete (if enabled)
- C_SaferCond cond_ctx;
- operation::SnapshotRollbackRequest<> *request =
- new operation::SnapshotRollbackRequest<>(*ictx, &cond_ctx, snap_name,
- snap_id, new_size, prog_ctx);
- request->send();
- r = cond_ctx.wait();
- if (r < 0) {
- return r;
- }
-
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
-
- ictx->perfcounter->inc(l_librbd_snap_rollback);
- return r;
- }
-
struct CopyProgressCtx {
CopyProgressCtx(ProgressContext &p)
: destictx(NULL), src_size(0), prog_ctx(p)
return 0;
}
- // 'flatten' child image by copying all parent's blocks
- int flatten(ImageCtx *ictx, ProgressContext &prog_ctx)
- {
- CephContext *cct = ictx->cct;
- ldout(cct, 20) << "flatten" << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0) {
- return r;
- }
-
- if (ictx->read_only) {
- return -EROFS;
- }
-
- {
- RWLock::RLocker parent_locker(ictx->parent_lock);
- if (ictx->parent_md.spec.pool_id == -1) {
- lderr(cct) << "image has no parent" << dendl;
- return -EINVAL;
- }
- }
-
- uint64_t request_id = ictx->async_request_seq.inc();
- r = invoke_async_request(ictx, "flatten", false,
- boost::bind(&async_flatten, ictx, _1,
- boost::ref(prog_ctx)),
- boost::bind(&ImageWatcher::notify_flatten,
- ictx->image_watcher, request_id,
- boost::ref(prog_ctx)));
-
- if (r < 0 && r != -EINVAL) {
- return r;
- }
-
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- ldout(cct, 20) << "flatten finished" << dendl;
- return 0;
- }
-
- void async_flatten(ImageCtx *ictx, Context *ctx, ProgressContext &prog_ctx)
- {
- assert(ictx->owner_lock.is_locked());
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
-
- CephContext *cct = ictx->cct;
- ldout(cct, 20) << "flatten" << dendl;
-
- uint64_t object_size;
- uint64_t overlap_objects;
- ::SnapContext snapc;
-
- {
- uint64_t overlap;
- RWLock::RLocker l(ictx->snap_lock);
- RWLock::RLocker l2(ictx->parent_lock);
-
- if (ictx->read_only) {
- ctx->complete(-EROFS);
- return;
- }
-
- // can't flatten a non-clone
- if (ictx->parent_md.spec.pool_id == -1) {
- lderr(cct) << "image has no parent" << dendl;
- ctx->complete(-EINVAL);
- return;
- }
- if (ictx->snap_id != CEPH_NOSNAP) {
- lderr(cct) << "snapshots cannot be flattened" << dendl;
- ctx->complete(-EROFS);
- return;
- }
-
- snapc = ictx->snapc;
- assert(ictx->parent != NULL);
- int r = ictx->get_parent_overlap(CEPH_NOSNAP, &overlap);
- assert(r == 0);
- assert(overlap <= ictx->size);
-
- object_size = ictx->get_object_size();
- overlap_objects = Striper::get_num_objects(ictx->layout, overlap);
- }
-
- operation::FlattenRequest<> *req = new operation::FlattenRequest<>(
- *ictx, ctx, object_size, overlap_objects, snapc, prog_ctx);
- req->send();
- }
-
- int rebuild_object_map(ImageCtx *ictx, ProgressContext &prog_ctx) {
- CephContext *cct = ictx->cct;
- ldout(cct, 10) << "rebuild_object_map" << dendl;
-
- int r = ictx->state->refresh_if_required();
- if (r < 0) {
- return r;
- }
-
- uint64_t request_id = ictx->async_request_seq.inc();
- r = invoke_async_request(ictx, "rebuild object map", true,
- boost::bind(&async_rebuild_object_map, ictx, _1,
- boost::ref(prog_ctx)),
- boost::bind(&ImageWatcher::notify_rebuild_object_map,
- ictx->image_watcher, request_id,
- boost::ref(prog_ctx)));
-
- ldout(cct, 10) << "rebuild object map finished" << dendl;
- if (r < 0) {
- notify_change(ictx->md_ctx, ictx->header_oid, ictx);
- }
- return r;
- }
-
- void async_rebuild_object_map(ImageCtx *ictx, Context *ctx,
- ProgressContext &prog_ctx) {
- assert(ictx->owner_lock.is_locked());
- assert(ictx->exclusive_lock == nullptr ||
- ictx->exclusive_lock->is_lock_owner());
-
- CephContext *cct = ictx->cct;
- ldout(cct, 20) << "async_rebuild_object_map " << ictx << dendl;
-
- if (ictx->read_only) {
- ctx->complete(-EROFS);
- return;
- }
- if (!ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
- ctx->complete(-EINVAL);
- return;
- }
-
- operation::RebuildObjectMapRequest<> *req =
- new operation::RebuildObjectMapRequest<>(*ictx, ctx, prog_ctx);
- req->send();
- }
-
int list_lockers(ImageCtx *ictx,
std::list<locker_t> *lockers,
bool *exclusive,
l_librbd_last,
};
-class Context;
-class RWLock;
-class SimpleThrottle;
-
namespace librbd {
struct AioCompletion;
int clone(IoCtx& p_ioctx, const char *p_name, const char *p_snap_name,
IoCtx& c_ioctx, const char *c_name, ImageOptions& c_opts);
int rename(librados::IoCtx& io_ctx, const char *srcname, const char *dstname);
- void rename_helper(ImageCtx *ictx, Context *ctx, const char *dstname);
int info(ImageCtx *ictx, image_info_t& info, size_t image_size);
int get_old_format(ImageCtx *ictx, uint8_t *old);
int get_size(ImageCtx *ictx, uint64_t *size);
int remove(librados::IoCtx& io_ctx, const char *imgname,
ProgressContext& prog_ctx);
- int resize(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx);
- int snap_create(ImageCtx *ictx, const char *snap_name);
- void snap_create_helper(ImageCtx *ictx, Context* ctx, const char *snap_name);
int snap_list(ImageCtx *ictx, std::vector<snap_info_t>& snaps);
int snap_exists(ImageCtx *ictx, const char *snap_name, bool *exists);
- int snap_rollback(ImageCtx *ictx, const char *snap_name,
- ProgressContext& prog_ctx);
- int snap_remove(ImageCtx *ictx, const char *snap_name);
- void snap_remove_helper(ImageCtx *ictx, Context* ctx, const char *snap_name);
- int snap_rename(ImageCtx *ictx, const char *srcname, const char *dstname);
- void snap_rename_helper(ImageCtx *ictx, Context* ctx,
- const uint64_t src_snap_id, const char *dst_name);
- int snap_protect(ImageCtx *ictx, const char *snap_name);
- void snap_protect_helper(ImageCtx *ictx, Context* ctx, const char *snap_name);
- int snap_unprotect(ImageCtx *ictx, const char *snap_name);
- void snap_unprotect_helper(ImageCtx *ictx, Context* ctx,
- const char *snap_name);
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);
int copy(ImageCtx *src, ImageCtx *dest, ProgressContext &prog_ctx);
- int flatten(ImageCtx *ictx, ProgressContext &prog_ctx);
-
- int rebuild_object_map(ImageCtx *ictx, ProgressContext &prog_ctx);
-
/* cooperative locking */
int list_lockers(ImageCtx *ictx,
std::list<locker_t> *locks,
void readahead(ImageCtx *ictx,
const vector<pair<uint64_t,uint64_t> >& image_extents);
- void async_flatten(ImageCtx *ictx, Context *ctx, ProgressContext &prog_ctx);
- void async_resize(ImageCtx *ictx, Context *ctx, uint64_t size,
- ProgressContext &prog_ctx);
- void async_rebuild_object_map(ImageCtx *ictx, Context *ctx,
- ProgressContext &prog_ctx);
-
int flush(ImageCtx *ictx);
int invalidate_cache(ImageCtx *ictx);
int poll_io_events(ImageCtx *ictx, AioCompletion **comps, int numcomp);
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
#include "librbd/internal.h"
-#include "librbd/LibrbdWriteback.h"
+#include "librbd/Operations.h"
#include <algorithm>
#include <string>
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::resize(ictx, size, prog_ctx);
+ int r = ictx->operations->resize(size, prog_ctx);
tracepoint(librbd, resize_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
- int r = librbd::resize(ictx, size, pctx);
+ int r = ictx->operations->resize(size, pctx);
tracepoint(librbd, resize_exit, r);
return r;
}
int Image::rebuild_object_map(ProgressContext &prog_ctx)
{
ImageCtx *ictx = reinterpret_cast<ImageCtx*>(ctx);
- return librbd::rebuild_object_map(ictx, prog_ctx);
+ return ictx->operations->rebuild_object_map(prog_ctx);
}
int Image::copy(IoCtx& dest_io_ctx, const char *destname)
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, flatten_enter, ictx, ictx->name.c_str(), ictx->id.c_str());
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::flatten(ictx, prog_ctx);
+ int r = ictx->operations->flatten(prog_ctx);
tracepoint(librbd, flatten_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, flatten_enter, ictx, ictx->name.c_str(), ictx->id.c_str());
- int r = librbd::flatten(ictx, prog_ctx);
+ int r = ictx->operations->flatten(prog_ctx);
tracepoint(librbd, flatten_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_create_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_create(ictx, snap_name);
+ int r = ictx->operations->snap_create(snap_name);
tracepoint(librbd, snap_create_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_remove_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_remove(ictx, snap_name);
+ int r = ictx->operations->snap_remove(snap_name);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_rollback_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::snap_rollback(ictx, snap_name, prog_ctx);
+ int r = ictx->operations->snap_rollback(snap_name, prog_ctx);
tracepoint(librbd, snap_rollback_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_rename_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, srcname, dstname);
- int r = librbd::snap_rename(ictx, srcname, dstname);
+ int r = ictx->operations->snap_rename(srcname, dstname);
tracepoint(librbd, snap_rename_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_rollback_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_rollback(ictx, snap_name, prog_ctx);
+ int r = ictx->operations->snap_rollback(snap_name, prog_ctx);
tracepoint(librbd, snap_rollback_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_protect_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_protect(ictx, snap_name);
+ int r = ictx->operations->snap_protect(snap_name);
tracepoint(librbd, snap_protect_exit, r);
return r;
}
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, snap_unprotect_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_unprotect(ictx, snap_name);
+ int r = ictx->operations->snap_unprotect(snap_name);
tracepoint(librbd, snap_unprotect_exit, r);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, flatten_enter, ictx, ictx->name.c_str(), ictx->id.c_str());
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::flatten(ictx, prog_ctx);
+ int r = ictx->operations->flatten(prog_ctx);
tracepoint(librbd, flatten_exit, r);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, flatten_enter, ictx, ictx->name.c_str(), ictx->id.c_str());
librbd::CProgressContext prog_ctx(cb, cbdata);
- int r = librbd::flatten(ictx, prog_ctx);
+ int r = ictx->operations->flatten(prog_ctx);
tracepoint(librbd, flatten_exit, r);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::resize(ictx, size, prog_ctx);
+ int r = ictx->operations->resize(size, prog_ctx);
tracepoint(librbd, resize_exit, r);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, resize_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, size);
librbd::CProgressContext prog_ctx(cb, cbdata);
- int r = librbd::resize(ictx, size, prog_ctx);
+ int r = ictx->operations->resize(size, prog_ctx);
tracepoint(librbd, resize_exit, r);
return r;
}
{
librbd::ImageCtx *ictx = reinterpret_cast<librbd::ImageCtx*>(image);
librbd::CProgressContext prog_ctx(cb, cbdata);
- return librbd::rebuild_object_map(ictx, prog_ctx);
+ return ictx->operations->rebuild_object_map(prog_ctx);
}
/* snapshots */
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_create_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_create(ictx, snap_name);
+ int r = ictx->operations->snap_create(snap_name);
tracepoint(librbd, snap_create_exit, r);
return r;
}
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_rename_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, srcname, dstname);
- int r = librbd::snap_rename(ictx, srcname, dstname);
+ int r = ictx->operations->snap_rename(srcname, dstname);
tracepoint(librbd, snap_rename_exit, r);
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);
- int r = librbd::snap_remove(ictx, snap_name);
+ int r = ictx->operations->snap_remove(snap_name);
tracepoint(librbd, snap_remove_exit, r);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_rollback_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
librbd::NoOpProgressContext prog_ctx;
- int r = librbd::snap_rollback(ictx, snap_name, prog_ctx);
+ int r = ictx->operations->snap_rollback(snap_name, prog_ctx);
tracepoint(librbd, snap_rollback_exit, r);
return r;
}
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_rollback_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
librbd::CProgressContext prog_ctx(cb, cbdata);
- int r = librbd::snap_rollback(ictx, snap_name, prog_ctx);
+ int r = ictx->operations->snap_rollback(snap_name, prog_ctx);
tracepoint(librbd, snap_rollback_exit, r);
return r;
}
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_protect_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_protect(ictx, snap_name);
+ int r = ictx->operations->snap_protect(snap_name);
tracepoint(librbd, snap_protect_exit, r);
return r;
}
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, snap_unprotect_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
- int r = librbd::snap_unprotect(ictx, snap_name);
+ int r = ictx->operations->snap_unprotect(snap_name);
tracepoint(librbd, snap_unprotect_exit, r);
return r;
}