From: Jason Dillaman Date: Fri, 11 Mar 2016 01:48:40 +0000 (-0500) Subject: librbd: async version of snap create and snap remove X-Git-Tag: v10.1.0~104^2~11 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1c8b62185f471c29e7f627adf0bd8d53fcbf5db2;p=ceph.git librbd: async version of snap create and snap remove This will be utilized by the RBD mirror daemon when creating sync points. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index ef33e436fc87..7279d25ee937 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -19,6 +19,7 @@ #include "librbd/operation/SnapshotRenameRequest.h" #include "librbd/operation/SnapshotRollbackRequest.h" #include "librbd/operation/SnapshotUnprotectRequest.h" +#include #include #define dout_subsys ceph_subsys_rbd @@ -84,16 +85,18 @@ struct C_InvokeAsyncRequest : public Context { bool permit_snapshot; boost::function local; boost::function remote; + std::set filter_error_codes; Context *on_finish; C_InvokeAsyncRequest(I &image_ctx, const std::string& request_type, bool permit_snapshot, const boost::function& local, const boost::function& remote, + const std::set &filter_error_codes, Context *on_finish) : image_ctx(image_ctx), request_type(request_type), permit_snapshot(permit_snapshot), local(local), remote(remote), - on_finish(on_finish) { + filter_error_codes(filter_error_codes), on_finish(on_finish) { } void send() { @@ -201,6 +204,9 @@ struct C_InvokeAsyncRequest : public Context { } virtual void finish(int r) override { + if (filter_error_codes.count(r) != 0) { + r = 0; + } on_finish->complete(r); } }; @@ -471,37 +477,53 @@ void Operations::execute_resize(uint64_t size, ProgressContext &prog_ctx, 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) + 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::execute_snap_create, - this, snap_name, _1, 0), - boost::bind(&ImageWatcher::notify_snap_create, - m_image_ctx.image_watcher, snap_name, - _1)); - if (r < 0 && r != -EEXIST) { + C_SaferCond ctx; + snap_create(snap_name, &ctx); + r = ctx.wait(); + + if (r < 0) { return r; } m_image_ctx.perfcounter->inc(l_librbd_snap_create); - return 0; + return r; +} + +template +void Operations::snap_create(const char *snap_name, Context *on_finish) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name + << dendl; + + if (m_image_ctx.read_only) { + on_finish->complete(-EROFS); + return; + } + + { + RWLock::RLocker snap_locker(m_image_ctx.snap_lock); + if (m_image_ctx.get_snap_id(snap_name) != CEPH_NOSNAP) { + on_finish->complete(-EEXIST); + return; + } + } + + C_InvokeAsyncRequest *req = new C_InvokeAsyncRequest( + m_image_ctx, "snap_create", true, + boost::bind(&Operations::execute_snap_create, this, snap_name, _1, 0), + boost::bind(&ImageWatcher::notify_snap_create, m_image_ctx.image_watcher, + snap_name, _1), + {-EEXIST}, on_finish); + req->send(); } template @@ -606,50 +628,61 @@ void Operations::execute_snap_rollback(const char *snap_name, 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) + if (m_image_ctx.read_only) { return -EROFS; + } int r = m_image_ctx.state->refresh_if_required(); - if (r < 0) + if (r < 0) { return r; + } + + C_SaferCond ctx; + snap_remove(snap_name, &ctx); + r = ctx.wait(); + + if (r < 0) { + return r; + } + + m_image_ctx.perfcounter->inc(l_librbd_snap_remove); + return 0; +} + +template +void Operations::snap_remove(const char *snap_name, Context *on_finish) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name + << dendl; + + if (m_image_ctx.read_only) { + on_finish->complete(-EROFS); + return; + } 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; + on_finish->complete(-ENOENT); + return; } 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::execute_snap_remove, - this, snap_name, _1), - boost::bind(&ImageWatcher::notify_snap_remove, - m_image_ctx.image_watcher, snap_name, - _1)); - if (r < 0 && r != -ENOENT) { - return r; - } + C_InvokeAsyncRequest *req = new C_InvokeAsyncRequest( + m_image_ctx, "snap_remove", true, + boost::bind(&Operations::execute_snap_remove, this, snap_name, _1), + boost::bind(&ImageWatcher::notify_snap_remove, m_image_ctx.image_watcher, + snap_name, _1), + {-ENOENT}, on_finish); + req->send(); } else { RWLock::RLocker owner_lock(m_image_ctx.owner_lock); - C_SaferCond cond_ctx; - execute_snap_remove(snap_name, &cond_ctx); - - r = cond_ctx.wait(); - if (r < 0) { - return r; - } + execute_snap_remove(snap_name, on_finish); } - - m_image_ctx.perfcounter->inc(l_librbd_snap_remove); - return 0; } template @@ -954,7 +987,7 @@ int Operations::invoke_async_request(const std::string& request_type, permit_snapshot, local_request, remote_request, - &ctx); + {}, &ctx); req->send(); return ctx.wait(); } diff --git a/src/librbd/Operations.h b/src/librbd/Operations.h index b05d5da54fb1..a32116a01566 100644 --- a/src/librbd/Operations.h +++ b/src/librbd/Operations.h @@ -36,6 +36,7 @@ public: Context *on_finish, uint64_t journal_op_tid); int snap_create(const char *snap_name); + void snap_create(const char *snap_name, Context *on_finish); void execute_snap_create(const char *snap_name, Context *on_finish, uint64_t journal_op_tid); @@ -44,6 +45,7 @@ public: Context *on_finish); int snap_remove(const char *snap_name); + void snap_remove(const char *snap_name, Context *on_finish); void execute_snap_remove(const char *snap_name, Context *on_finish); int snap_rename(const char *srcname, const char *dstname);