From 983d12b500f728f6b9eff888d091d9f652e468fc Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 25 Aug 2015 11:17:57 -0400 Subject: [PATCH] librbd: snap protect/unprotect now connected to watch/notify Signed-off-by: Jason Dillaman --- src/librbd/ImageWatcher.cc | 16 +++-- src/librbd/internal.cc | 136 +++++++++++++++++++++++++++++++------ src/librbd/internal.h | 3 + 3 files changed, 128 insertions(+), 27 deletions(-) diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 87aebf0d9084f..6cbab0022173a 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -1091,9 +1091,12 @@ void ImageWatcher::handle_payload(const SnapProtectPayload& payload, if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) { ldout(m_image_ctx.cct, 10) << this << " remote snap_protect request: " << payload.snap_name << dendl; + C_SaferCond cond_ctx; + librbd::snap_protect_helper(&m_image_ctx, &cond_ctx, + payload.snap_name.c_str()); - // TODO - ::encode(ResponseMessage(-EOPNOTSUPP), *out); + int r = cond_ctx.wait(); + ::encode(ResponseMessage(r), *out); } } @@ -1103,9 +1106,12 @@ void ImageWatcher::handle_payload(const SnapUnprotectPayload& payload, if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) { ldout(m_image_ctx.cct, 10) << this << " remote snap_unprotect request: " << payload.snap_name << dendl; + C_SaferCond cond_ctx; + librbd::snap_unprotect_helper(&m_image_ctx, &cond_ctx, + payload.snap_name.c_str()); - // TODO - ::encode(ResponseMessage(-EOPNOTSUPP), *out); + int r = cond_ctx.wait(); + ::encode(ResponseMessage(r), *out); } } @@ -1125,7 +1131,7 @@ void ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload, librbd::async_rebuild_object_map(&m_image_ctx, ctx, *prog_ctx); } - ::encode(ResponseMessage(0), *out); + ::encode(ResponseMessage(r), *out); } } diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index accf5e0fdfa80..8efec10d2f5cf 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -903,57 +903,149 @@ int invoke_async_request(ImageCtx *ictx, const std::string& request_type, ldout(ictx->cct, 20) << "snap_protect " << ictx << " " << snap_name << dendl; - if (ictx->read_only) + if (ictx->read_only) { return -EROFS; + } int r = ictx_check(ictx); - if (r < 0) + if (r < 0) { return r; + } - // TODO integrate w/ watch/notify - RWLock::RLocker owner_locker(ictx->owner_lock); + { + 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; + } - C_SaferCond cond_ctx; - operation::SnapshotProtectRequest *request = - new operation::SnapshotProtectRequest(*ictx, &cond_ctx, snap_name); - request->send(); - r = cond_ctx.wait(); - 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->image_watcher->is_lock_supported() || + ictx->image_watcher->is_lock_owner()); + } + + ldout(ictx->cct, 20) << "snap_protect_helper " << ictx << " " << snap_name + << dendl; + + int r = ictx_check(ictx, ictx->owner_lock); + if (r < 0) { + ctx->complete(r); + return; + } + + 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) + if (ictx->read_only) { return -EROFS; + } int r = ictx_check(ictx); - if (r < 0) + if (r < 0) { return r; + } - // TODO integrate w/ watch/notify - RWLock::RLocker owner_locker(ictx->owner_lock); + { + 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; + } - C_SaferCond cond_ctx; - operation::SnapshotUnprotectRequest *request - = new operation::SnapshotUnprotectRequest(*ictx, &cond_ctx, snap_name); - request->send(); - r = cond_ctx.wait(); - 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->image_watcher->is_lock_supported() || + ictx->image_watcher->is_lock_owner()); + } + + ldout(ictx->cct, 20) << "snap_unprotect_helper " << ictx << " " << snap_name + << dendl; + + int r = ictx_check(ictx, ictx->owner_lock); + if (r < 0) { + ctx->complete(r); + return; + } + + 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) { diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 2300fcc998cbe..964dde68d21bf 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -137,7 +137,10 @@ namespace librbd { 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 refresh_parent(ImageCtx *ictx); -- 2.39.5