From: Jason Dillaman Date: Thu, 28 Apr 2016 15:46:20 +0000 (-0400) Subject: librbd: refresh image before executing maint op X-Git-Tag: v11.0.0~793^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9cf6821bd9f58c181720a5c8156cec5ab33d35d4;p=ceph.git librbd: refresh image before executing maint op If a maint op is interrupted and restarted, it's possible that the image will need to be refreshed. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index 81219d4a745a..3b15625ba788 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -79,6 +79,9 @@ struct C_InvokeAsyncRequest : public Context { * . . . . . . | . . . . . . . . . . . . . . . . . . * . . | . . * . v v v . + * . REFRESH_IMAGE (skip if not needed) . + * . | . + * . v . * . ACQUIRE_LOCK (skip if exclusive lock . * . | disabled or has lock) . * . | . @@ -116,6 +119,35 @@ struct C_InvokeAsyncRequest : public Context { } void send() { + send_refresh_image(); + } + + void send_refresh_image() { + if (!image_ctx.state->is_refresh_required()) { + send_acquire_exclusive_lock(); + return; + } + + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << dendl; + + Context *ctx = util::create_context_callback< + C_InvokeAsyncRequest, + &C_InvokeAsyncRequest::handle_refresh_image>(this); + image_ctx.state->refresh(ctx); + } + + void handle_refresh_image(int r) { + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << ": r=" << r << dendl; + + RWLock::RLocker owner_locker(image_ctx.owner_lock); + if (r < 0) { + lderr(cct) << "failed to refresh image: " << cpp_strerror(r) << dendl; + complete(r); + return; + } + send_acquire_exclusive_lock(); } @@ -193,7 +225,7 @@ struct C_InvokeAsyncRequest : public Context { ldout(cct, 5) << request_type << " timed out notifying lock owner" << dendl; - send_acquire_exclusive_lock(); + send_refresh_image(); } void send_local_request() { @@ -213,7 +245,7 @@ struct C_InvokeAsyncRequest : public Context { ldout(cct, 20) << __func__ << ": r=" << r << dendl; if (r == -ERESTART) { - send_acquire_exclusive_lock(); + send_refresh_image(); return; } complete(r); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 5276052c5190..3ac77935baff 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1589,40 +1589,40 @@ remove_mirroring_image: return -EINVAL; } - { - RWLock::RLocker owner_locker(ictx->owner_lock); - RWLock::WLocker md_locker(ictx->md_lock); - r = ictx->flush(); - if (r < 0) { - return r; - } + RWLock::RLocker owner_locker(ictx->owner_lock); + RWLock::WLocker md_locker(ictx->md_lock); + r = ictx->flush(); + if (r < 0) { + return r; + } - uint64_t disable_mask = (RBD_FEATURES_MUTABLE | - RBD_FEATURES_DISABLE_ONLY); - if ((enabled && (features & RBD_FEATURES_MUTABLE) != features) || - (!enabled && (features & disable_mask) != features)) { - lderr(cct) << "cannot update immutable features" << dendl; - return -EINVAL; - } else if (features == 0) { - lderr(cct) << "update requires at least one feature" << dendl; - return -EINVAL; - } + uint64_t disable_mask = (RBD_FEATURES_MUTABLE | + RBD_FEATURES_DISABLE_ONLY); + if ((enabled && (features & RBD_FEATURES_MUTABLE) != features) || + (!enabled && (features & disable_mask) != features)) { + lderr(cct) << "cannot update immutable features" << dendl; + return -EINVAL; + } else if (features == 0) { + lderr(cct) << "update requires at least one feature" << dendl; + return -EINVAL; + } - // if disabling features w/ exclusive lock supported, we need to - // acquire the lock to temporarily block IO against the image - if (ictx->exclusive_lock != nullptr && !enabled) { - C_SaferCond lock_ctx; - ictx->exclusive_lock->request_lock(&lock_ctx); - r = lock_ctx.wait(); - if (r < 0) { - lderr(cct) << "failed to lock image: " << cpp_strerror(r) << dendl; - return r; - } else if (!ictx->exclusive_lock->is_lock_owner()) { - lderr(cct) << "failed to acquire exclusive lock" << dendl; - return -EROFS; - } + // if disabling features w/ exclusive lock supported, we need to + // acquire the lock to temporarily block IO against the image + if (ictx->exclusive_lock != nullptr && !enabled) { + C_SaferCond lock_ctx; + ictx->exclusive_lock->request_lock(&lock_ctx); + r = lock_ctx.wait(); + if (r < 0) { + lderr(cct) << "failed to lock image: " << cpp_strerror(r) << dendl; + return r; + } else if (!ictx->exclusive_lock->is_lock_owner()) { + lderr(cct) << "failed to acquire exclusive lock" << dendl; + return -EROFS; } + } + { RWLock::WLocker snap_locker(ictx->snap_lock); uint64_t new_features; if (enabled) { @@ -1799,7 +1799,7 @@ remove_mirroring_image: img_ctx->state->close(); } } - } + } ictx->notify_update(); return 0;