void AbstractWrite::send_pre() {
assert(m_ictx->owner_lock.is_locked());
- RWLock::RLocker snap_lock(m_ictx->snap_lock);
- if (!m_ictx->object_map.enabled()) {
- send_write();
- return;
- }
-
- // should have been flushed prior to releasing lock
- assert(m_ictx->image_watcher->is_lock_owner());
-
- ldout(m_ictx->cct, 20) << "send_pre " << this << " " << m_oid << " "
- << m_object_off << "~" << m_object_len << dendl;
- m_state = LIBRBD_AIO_WRITE_PRE;
-
- uint8_t new_state;
- boost::optional<uint8_t> current_state;
- pre_object_map_update(&new_state);
+ bool write = false;
+ {
+ RWLock::RLocker snap_lock(m_ictx->snap_lock);
+ if (!m_ictx->object_map.enabled()) {
+ write = true;
+ } else {
+ // should have been flushed prior to releasing lock
+ assert(m_ictx->image_watcher->is_lock_owner());
+
+ ldout(m_ictx->cct, 20) << "send_pre " << this << " " << m_oid << " "
+ << m_object_off << "~" << m_object_len << dendl;
+ m_state = LIBRBD_AIO_WRITE_PRE;
+
+ uint8_t new_state;
+ boost::optional<uint8_t> current_state;
+ pre_object_map_update(&new_state);
+
+ RWLock::WLocker object_map_locker(m_ictx->object_map_lock);
+ if (m_ictx->object_map[m_object_no] != new_state) {
+ FunctionContext *ctx = new FunctionContext(
+ boost::bind(&AioRequest::complete, this, _1));
+ bool updated = m_ictx->object_map.aio_update(m_object_no, new_state,
+ current_state, ctx);
+ assert(updated);
+ } else {
+ write = true;
+ }
+ }
+ }
- RWLock::WLocker object_map_locker(m_ictx->object_map_lock);
- if (m_ictx->object_map[m_object_no] == new_state) {
+ // avoid possible recursive lock attempts
+ if (write) {
+ // no object map update required
send_write();
- return;
}
-
- FunctionContext *ctx = new FunctionContext(
- boost::bind(&AioRequest::complete, this, _1));
- bool updated = m_ictx->object_map.aio_update(m_object_no, new_state,
- current_state, ctx);
- assert(updated);
}
bool AbstractWrite::send_post() {
wr->write(m_object_off, m_write_data);
wr->set_op_flags2(m_op_flags);
}
+
+ void AioRemove::guard_write() {
+ // do nothing to disable write guard only if deep-copyup not required
+ RWLock::RLocker snap_locker(m_ictx->snap_lock);
+ if (!m_ictx->snaps.empty()) {
+ AbstractWrite::guard_write();
+ }
+ }
}