mirror of
https://github.com/ceph/ceph
synced 2025-04-01 23:02:17 +00:00
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 <dillaman@redhat.com>
This commit is contained in:
parent
5a4893b7a7
commit
9cf6821bd9
src/librbd
@ -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<I>,
|
||||
&C_InvokeAsyncRequest<I>::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);
|
||||
|
@ -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();
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user