* . . . . . . | . . . . . . . . . . . . . . . . . .
* . . | . .
* . v v v .
+ * . REFRESH_IMAGE (skip if not needed) .
+ * . | .
+ * . v .
* . ACQUIRE_LOCK (skip if exclusive lock .
* . | disabled or has lock) .
* . | .
}
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();
}
ldout(cct, 5) << request_type << " timed out notifying lock owner"
<< dendl;
- send_acquire_exclusive_lock();
+ send_refresh_image();
}
void send_local_request() {
ldout(cct, 20) << __func__ << ": r=" << r << dendl;
if (r == -ERESTART) {
- send_acquire_exclusive_lock();
+ send_refresh_image();
return;
}
complete(r);
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) {
img_ctx->state->close();
}
}
- }
+ }
ictx->notify_update();
return 0;