return 0;
}
-void ImageWatcher::release_lock()
+bool ImageWatcher::release_lock()
{
+ assert(m_image_ctx.owner_lock.is_wlocked());
ldout(m_image_ctx.cct, 10) << "releasing exclusive lock by request" << dendl;
- {
- RWLock::WLocker l(m_image_ctx.owner_lock);
- if (!is_lock_owner()) {
- return;
- }
- prepare_unlock();
+ if (!is_lock_owner()) {
+ return false;
}
+ prepare_unlock();
+ m_image_ctx.owner_lock.put_write();
m_image_ctx.cancel_async_requests();
+ m_image_ctx.owner_lock.get_write();
- RWLock::WLocker l(m_image_ctx.owner_lock);
if (!is_lock_owner()) {
- return;
+ return false;
}
{
}
unlock();
+ return true;
}
void ImageWatcher::finalize_header_update() {
return ClientId(m_image_ctx.md_ctx.get_instance_id(), m_watch_handle);
}
+void ImageWatcher::notify_release_lock() {
+ RWLock::WLocker owner_locker(m_image_ctx.owner_lock);
+ release_lock();
+}
+
void ImageWatcher::notify_released_lock() {
ldout(m_image_ctx.cct, 10) << "notify released lock" << dendl;
bufferlist bl;
ldout(m_image_ctx.cct, 10) << "queuing release of exclusive lock" << dendl;
FunctionContext *ctx = new FunctionContext(
- boost::bind(&ImageWatcher::release_lock, this));
+ boost::bind(&ImageWatcher::notify_release_lock, this));
m_task_finisher->queue(TASK_CODE_RELEASING_LOCK, ctx);
}
}
{
RWLock::WLocker l(m_image_ctx.owner_lock);
- bool lock_owner = (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED);
- if (lock_owner) {
- unlock();
+ bool was_lock_owner = false;
+ if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) {
+ // ensure all async requests are canceled and IO is flushed
+ was_lock_owner = release_lock();
}
int r;
}
handle_payload(HeaderUpdatePayload(), NULL);
- if (lock_owner) {
+ if (was_lock_owner) {
r = try_lock();
if (r == -EBUSY) {
ldout(m_image_ctx.cct, 5) << "lost image lock while re-registering "
int get_lock_owner_info(entity_name_t *locker, std::string *cookie,
std::string *address, uint64_t *handle);
int lock();
- void release_lock();
+ bool release_lock();
bool try_request_lock();
void finalize_header_update();
WatchNotify::ClientId get_client_id();
+ void notify_release_lock();
void notify_released_lock();
void notify_request_lock();
int notify_lock_owner(bufferlist &bl);