From: Jason Dillaman Date: Thu, 17 Dec 2015 15:46:00 +0000 (-0500) Subject: librbd: moved all maintenance ops to new Operations class X-Git-Tag: v10.0.3~24^2~14 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=629c6f0d7c6c8655a4d358bba2fdb4b6c810d12e;p=ceph.git librbd: moved all maintenance ops to new Operations class This will permit unit testing and will facilitate proper serialization of requests (when necessary). Signed-off-by: Jason Dillaman --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10d86c2ab7f6..ad31eb1fede7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -978,6 +978,7 @@ if(${WITH_RBD}) 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 diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index ef7861f332df..e432d637dd56 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -21,6 +21,7 @@ #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" @@ -162,8 +163,11 @@ struct C_InvalidateCache : public Context { 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); @@ -217,6 +221,7 @@ struct C_InvalidateCache : public Context { delete op_work_queue; delete aio_work_queue; delete asok_hook; + delete operations; delete state; } diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index 451d14ff72ce..7606f6fbf7d6 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -50,6 +50,7 @@ namespace librbd { template class Journal; class LibrbdAdminSocketHook; class ObjectMap; + template class Operations; namespace operation { template class ResizeRequest; @@ -137,11 +138,11 @@ namespace librbd { std::list async_requests_waiters; ImageState *state; + Operations *operations; + ExclusiveLock *exclusive_lock; ObjectMap *object_map; - atomic_t async_request_seq; - xlist*> resize_reqs; AioImageRequestWQ *aio_work_queue; diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index ea3dbe0d7b6d..d28541f39684 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -7,6 +7,7 @@ #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" @@ -630,7 +631,7 @@ bool ImageWatcher::handle_payload(const FlattenPayload &payload, 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); @@ -652,7 +653,7 @@ bool ImageWatcher::handle_payload(const ResizePayload &payload, 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); @@ -668,8 +669,8 @@ bool ImageWatcher::handle_payload(const SnapCreatePayload &payload, 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; @@ -684,8 +685,9 @@ bool ImageWatcher::handle_payload(const SnapRenamePayload &payload, << 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; @@ -699,8 +701,8 @@ bool ImageWatcher::handle_payload(const SnapRemovePayload &payload, 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; @@ -714,8 +716,8 @@ bool ImageWatcher::handle_payload(const SnapProtectPayload& payload, 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; @@ -729,8 +731,8 @@ bool ImageWatcher::handle_payload(const SnapUnprotectPayload& payload, 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; @@ -750,7 +752,7 @@ bool ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, 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); @@ -766,8 +768,8 @@ bool ImageWatcher::handle_payload(const RenamePayload& payload, 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; diff --git a/src/librbd/Makefile.am b/src/librbd/Makefile.am index c02ca981abe9..775d7027551e 100644 --- a/src/librbd/Makefile.am +++ b/src/librbd/Makefile.am @@ -26,6 +26,7 @@ librbd_internal_la_SOURCES = \ 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 \ @@ -100,6 +101,7 @@ noinst_HEADERS += \ librbd/LibrbdAdminSocketHook.h \ librbd/LibrbdWriteback.h \ librbd/ObjectMap.h \ + librbd/Operations.h \ librbd/parent_types.h \ librbd/SnapInfo.h \ librbd/TaskFinisher.h \ diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc new file mode 100644 index 000000000000..456404087a16 --- /dev/null +++ b/src/librbd/Operations.cc @@ -0,0 +1,809 @@ +// -*- 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 + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::Operations: " + +namespace librbd { + +template +Operations::Operations(I &image_ctx) : m_image_ctx(image_ctx) { +} + +template +int Operations::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::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 +void Operations::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 *req = new operation::FlattenRequest( + m_image_ctx, on_finish, object_size, overlap_objects, snapc, prog_ctx); + req->send(); +} + +template +int Operations::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::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 +void Operations::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 *req = + new operation::RebuildObjectMapRequest(m_image_ctx, on_finish, prog_ctx); + req->send(); +} + +template +int Operations::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::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 +void Operations::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 *req = + new operation::RenameRequest(m_image_ctx, on_finish, dstname); + req->send(); +} + +template +int Operations::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::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 +void Operations::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 *req = new operation::ResizeRequest( + m_image_ctx, on_finish, size, prog_ctx); + req->send(); +} + +template +int Operations::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::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 +void Operations::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 *req = + new operation::SnapshotCreateRequest(m_image_ctx, on_finish, snap_name); + req->send(); +} + +template +int Operations::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 +void Operations::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 *request = + new operation::SnapshotRollbackRequest(m_image_ctx, on_finish, snap_name, + snap_id, new_size, prog_ctx); + request->send(); +} + +template +int Operations::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::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 +void Operations::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 *req = + new operation::SnapshotRemoveRequest(m_image_ctx, on_finish, snap_name, + snap_id); + req->send(); +} + +template +int Operations::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::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 +void Operations::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 *req = + new operation::SnapshotRenameRequest(m_image_ctx, on_finish, src_snap_id, + dst_name); + req->send(); +} + +template +int Operations::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::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 +void Operations::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 *request = + new operation::SnapshotProtectRequest(m_image_ctx, on_finish, snap_name); + request->send(); +} + +template +int Operations::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::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 +void Operations::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 *request = + new operation::SnapshotUnprotectRequest(m_image_ctx, on_finish, + snap_name); + request->send(); +} + +template +int Operations::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 +int Operations::invoke_async_request(const std::string& request_type, + bool permit_snapshot, + const boost::function& local_request, + const boost::function& 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 +void Operations::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; diff --git a/src/librbd/Operations.h b/src/librbd/Operations.h new file mode 100644 index 000000000000..e600950da6f3 --- /dev/null +++ b/src/librbd/Operations.h @@ -0,0 +1,73 @@ +// -*- 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 +#include + +class Context; + +namespace librbd { + +class ImageCtx; +class ProgressContext; + +template +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& local_request, + const boost::function& remote_request); + void notify_change(); +}; + +} // namespace librbd + +extern template class librbd::Operations; + +#endif // CEPH_LIBRBD_OPERATIONS_H diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 6f034f45352e..a926e03731cf 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -32,18 +32,9 @@ #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" @@ -127,7 +118,6 @@ int create_object_map(ImageCtx *ictx) { return 0; } - int update_all_flags(ImageCtx *ictx, uint64_t flags, uint64_t mask) { assert(ictx->snap_lock.is_locked()); CephContext *cct = ictx->cct; @@ -152,79 +142,6 @@ int update_all_flags(ImageCtx *ictx, uint64_t flags, uint64_t mask) { 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& local_request, - const boost::function& 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; @@ -776,340 +693,6 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { 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) { @@ -1676,57 +1259,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { 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) @@ -2050,7 +1583,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { 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(); @@ -2161,60 +1694,6 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { 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& snaps) { ldout(ictx->cct, 20) << "snap_list " << ictx << dendl; @@ -2249,85 +1728,6 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { 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) @@ -2530,143 +1930,6 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { 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 *lockers, bool *exclusive, diff --git a/src/librbd/internal.h b/src/librbd/internal.h index cbcc8b10c89c..9fac1c14cad0 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -47,10 +47,6 @@ enum { l_librbd_last, }; -class Context; -class RWLock; -class SimpleThrottle; - namespace librbd { struct AioCompletion; @@ -107,7 +103,6 @@ namespace librbd { 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); @@ -122,33 +117,14 @@ namespace librbd { 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& 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 *locks, @@ -189,12 +165,6 @@ namespace librbd { void readahead(ImageCtx *ictx, const vector >& 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); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 0807359af169..3fda9db3ce5d 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -30,7 +30,7 @@ #include "librbd/ImageCtx.h" #include "librbd/ImageState.h" #include "librbd/internal.h" -#include "librbd/LibrbdWriteback.h" +#include "librbd/Operations.h" #include #include @@ -439,7 +439,7 @@ namespace librbd { 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; } @@ -448,7 +448,7 @@ namespace librbd { { 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; } @@ -566,7 +566,7 @@ namespace librbd { int Image::rebuild_object_map(ProgressContext &prog_ctx) { ImageCtx *ictx = reinterpret_cast(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) @@ -638,7 +638,7 @@ namespace librbd { 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; } @@ -647,7 +647,7 @@ namespace librbd { { 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; } @@ -723,7 +723,7 @@ namespace librbd { { 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; } @@ -732,7 +732,7 @@ namespace librbd { { 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; } @@ -742,7 +742,7 @@ namespace librbd { 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; } @@ -751,7 +751,7 @@ namespace librbd { { 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; } @@ -761,7 +761,7 @@ namespace librbd { { 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; } @@ -770,7 +770,7 @@ namespace librbd { { 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; } @@ -779,7 +779,7 @@ namespace librbd { { 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; } @@ -1527,7 +1527,7 @@ extern "C" int rbd_flatten(rbd_image_t image) 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; } @@ -1538,7 +1538,7 @@ extern "C" int rbd_flatten_with_progress(rbd_image_t image, 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; } @@ -1611,7 +1611,7 @@ extern "C" int rbd_resize(rbd_image_t image, uint64_t size) 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; } @@ -1622,7 +1622,7 @@ extern "C" int rbd_resize_with_progress(rbd_image_t image, uint64_t size, 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; } @@ -1779,7 +1779,7 @@ extern "C" int rbd_rebuild_object_map(rbd_image_t image, { librbd::ImageCtx *ictx = reinterpret_cast(image); librbd::CProgressContext prog_ctx(cb, cbdata); - return librbd::rebuild_object_map(ictx, prog_ctx); + return ictx->operations->rebuild_object_map(prog_ctx); } /* snapshots */ @@ -1787,7 +1787,7 @@ extern "C" int rbd_snap_create(rbd_image_t image, const char *snap_name) { 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; } @@ -1796,7 +1796,7 @@ extern "C" int rbd_snap_rename(rbd_image_t image, const char *srcname, const cha { 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; } @@ -1805,7 +1805,7 @@ extern "C" int rbd_snap_remove(rbd_image_t image, const char *snap_name) { 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; } @@ -1815,7 +1815,7 @@ extern "C" int rbd_snap_rollback(rbd_image_t image, const char *snap_name) 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; } @@ -1828,7 +1828,7 @@ extern "C" int rbd_snap_rollback_with_progress(rbd_image_t image, 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; } @@ -1897,7 +1897,7 @@ extern "C" int rbd_snap_protect(rbd_image_t image, const char *snap_name) { 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; } @@ -1906,7 +1906,7 @@ extern "C" int rbd_snap_unprotect(rbd_image_t image, const char *snap_name) { 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; }