ProgressContext &prog_ctx)
: AsyncRequest(image_ctx, on_finish),
m_original_size(original_size), m_new_size(new_size),
- m_prog_ctx(prog_ctx), m_original_parent_overlap(0),
- m_new_parent_overlap(0), m_xlist_item(this)
+ m_prog_ctx(prog_ctx), m_new_parent_overlap(0),
+ m_xlist_item(this)
{
RWLock::WLocker l(m_image_ctx.snap_lock);
m_image_ctx.async_resize_reqs.push_back(&m_xlist_item);
+ compute_parent_overlap();
}
AsyncResizeRequest::~AsyncResizeRequest() {
assert(m_xlist_item.remove_myself());
if (!m_image_ctx.async_resize_reqs.empty()) {
next_req = m_image_ctx.async_resize_reqs.front();
+ next_req->compute_parent_overlap();
}
}
if (r < 0) {
lderr(cct) << "resize encountered an error: " << cpp_strerror(r) << dendl;
- RWLock::WLocker l(m_image_ctx.snap_lock);
- if (m_image_ctx.size == m_new_size) {
- m_image_ctx.size = m_original_size;
- }
-
- RWLock::WLocker l2(m_image_ctx.parent_lock);
- if (m_image_ctx.parent != NULL &&
- m_image_ctx.parent_md.overlap == m_new_parent_overlap) {
- m_image_ctx.parent_md.overlap = m_original_parent_overlap;
- }
return true;
}
case STATE_UPDATE_HEADER:
ldout(cct, 5) << "UPDATE_HEADER" << dendl;
if (send_shrink_object_map()) {
+ update_size_and_overlap();
+ increment_refresh_seq();
return true;
}
break;
case STATE_SHRINK_OBJECT_MAP:
ldout(cct, 5) << "SHRINK_OBJECT_MAP" << dendl;
+ update_size_and_overlap();
+ increment_refresh_seq();
return true;
case STATE_FINISHED:
<< " new_size=" << m_new_size << dendl;
m_state = STATE_FLUSH;
- {
- // update in-memory size to clip concurrent IO operations
- RWLock::WLocker l(m_image_ctx.snap_lock);
- m_image_ctx.size = m_new_size;
-
- RWLock::WLocker l2(m_image_ctx.parent_lock);
- if (m_image_ctx.parent != NULL) {
- m_original_parent_overlap = m_image_ctx.parent_md.overlap;
- m_new_parent_overlap = MIN(m_new_size, m_original_parent_overlap);
- m_image_ctx.parent_md.overlap = m_new_parent_overlap;
- }
- }
-
// with clipping adjusted, ensure that write / copy-on-read operations won't
// (re-)create objects that we just removed
m_image_ctx.flush_async_operations(create_callback_context());
bool lost_exclusive_lock = false;
{
RWLock::RLocker l(m_image_ctx.owner_lock);
- if (!m_image_ctx.object_map.enabled() ||
- m_new_size > m_original_size) {
+ if (!m_image_ctx.object_map.enabled() || m_new_size > m_original_size) {
return true;
}
m_state = STATE_UPDATE_HEADER;
{
- RWLock::RLocker l(m_image_ctx.owner_lock);
+ RWLock::RLocker l(m_image_ctx.owner_lock);
if (m_image_ctx.image_watcher->is_lock_supported() &&
!m_image_ctx.image_watcher->is_lock_owner()) {
ldout(m_image_ctx.cct, 1) << "lost exclusive lock during header update" << dendl;
lost_exclusive_lock = true;
} else {
- m_image_ctx.snap_lock.get_write();
- m_image_ctx.size = m_new_size;
- m_image_ctx.snap_lock.put_write();
-
librados::ObjectWriteOperation op;
if (m_image_ctx.old_format) {
// rewrite header
}
}
+void AsyncResizeRequest::compute_parent_overlap() {
+ RWLock::RLocker l2(m_image_ctx.parent_lock);
+ if (m_image_ctx.parent == NULL) {
+ m_new_parent_overlap = 0;
+ } else {
+ m_new_parent_overlap = MIN(m_new_size, m_image_ctx.parent_md.overlap);
+ }
+}
+
+void AsyncResizeRequest::increment_refresh_seq() {
+ m_image_ctx.refresh_lock.Lock();
+ ++m_image_ctx.refresh_seq;
+ m_image_ctx.refresh_lock.Unlock();
+}
+
+void AsyncResizeRequest::update_size_and_overlap() {
+ RWLock::WLocker snap_locker(m_image_ctx.snap_lock);
+ m_image_ctx.size = m_new_size;
+
+ RWLock::WLocker parent_locker(m_image_ctx.parent_lock);
+ if (m_image_ctx.parent != NULL && m_new_size < m_original_size) {
+ m_image_ctx.parent_md.overlap = m_new_parent_overlap;
+ }
+}
+
} // namespace librbd