ldout(m_ictx->cct, 20) << "WRITE_CHECK_GUARD" << dendl;
if (r == -ENOENT) {
- bool has_parent;
- {
- RWLock::RLocker snap_locker(m_ictx->snap_lock);
- RWLock::RLocker parent_locker(m_ictx->parent_lock);
- has_parent = compute_parent_extents();
- }
-
- // If parent still exists, overlap might also have changed.
- if (has_parent) {
- send_copyup();
- } else {
- // parent may have disappeared -- send original write again
- ldout(m_ictx->cct, 20) << "should_complete(" << this
- << "): parent overlap now 0" << dendl;
- send_write();
- }
+ handle_write_guard();
finished = false;
break;
} else if (r < 0) {
void AbstractWrite::send_pre() {
assert(m_ictx->owner_lock.is_locked());
+ m_object_exist = m_ictx->object_map.object_may_exist(m_object_no);
bool write = false;
{
RWLock::RLocker snap_lock(m_ictx->snap_lock);
void AbstractWrite::send_write() {
ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid << " "
- << m_object_off << "~" << m_object_len << dendl;
+ << m_object_off << "~" << m_object_len
+ << " object exist " << m_object_exist << dendl;
- m_state = LIBRBD_AIO_WRITE_FLAT;
- guard_write();
- add_write_ops(&m_write);
- assert(m_write.size() != 0);
-
- librados::AioCompletion *rados_completion =
- librados::Rados::aio_create_completion(this, NULL, rados_req_cb);
- int r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write,
- m_snap_seq, m_snaps);
- assert(r == 0);
- rados_completion->release();
+ if (!m_object_exist && has_parent()) {
+ m_state = LIBRBD_AIO_WRITE_GUARD;
+ handle_write_guard();
+ } else {
+ send_write_op(true);
+ }
}
void AbstractWrite::send_copyup()
m_ictx->copyup_list_lock.Unlock();
}
}
+ void AbstractWrite::send_write_op(bool write_guard)
+ {
+ m_state = LIBRBD_AIO_WRITE_FLAT;
+ if (write_guard)
+ guard_write();
+ add_write_ops(&m_write);
+ assert(m_write.size() != 0);
+
+ librados::AioCompletion *rados_completion =
+ librados::Rados::aio_create_completion(this, NULL, rados_req_cb);
+ int r = m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write,
+ m_snap_seq, m_snaps);
+ assert(r == 0);
+ rados_completion->release();
+ }
+ void AbstractWrite::handle_write_guard()
+ {
+ bool has_parent;
+ {
+ RWLock::RLocker snap_locker(m_ictx->snap_lock);
+ RWLock::RLocker parent_locker(m_ictx->parent_lock);
+ has_parent = compute_parent_extents();
+ }
+ // If parent still exists, overlap might also have changed.
+ if (has_parent) {
+ send_copyup();
+ } else {
+ // parent may have disappeared -- send original write again
+ ldout(m_ictx->cct, 20) << "should_complete(" << this
+ << "): parent overlap now 0" << dendl;
+ send_write();
+ }
+ }
void AioWrite::add_write_ops(librados::ObjectWriteOperation *wr) {
if (m_ictx->enable_alloc_hint && !m_ictx->object_map.object_may_exist(m_object_no))
AbstractWrite::guard_write();
}
}
+ void AioRemove::send_write() {
+ ldout(m_ictx->cct, 20) << "send_write " << this << " " << m_oid << " "
+ << m_object_off << "~" << m_object_len << dendl;
+ send_write_op(true);
+ }
}
virtual bool should_complete(int r);
virtual void send();
- private:
/**
* Writes go through the following state machine to deal with
* layering and the object map:
* The write starts in _WRITE_GUARD or _FLAT depending on whether or not
* there is a parent overlap.
*/
+ protected:
enum write_state_d {
LIBRBD_AIO_WRITE_GUARD,
LIBRBD_AIO_WRITE_COPYUP,
LIBRBD_AIO_WRITE_ERROR
};
- protected:
write_state_d m_state;
librados::ObjectWriteOperation m_write;
uint64_t m_snap_seq;
std::vector<librados::snap_t> m_snaps;
+ bool m_object_exist;
virtual void add_write_ops(librados::ObjectWriteOperation *wr) = 0;
virtual const char* get_write_type() const = 0;
virtual bool post_object_map_update() {
return false;
}
+ virtual void send_write();
+ virtual void send_write_op(bool write_guard);
+ virtual void handle_write_guard();
private:
void send_pre();
bool send_post();
- void send_write();
void send_copyup();
};
}
virtual void guard_write();
+ virtual void send_write();
private:
uint8_t m_object_state;