#define dout_subsys ceph_subsys_rbd
#undef dout_prefix
-#define dout_prefix *_dout << "librbd::ResizeRequest: "
+#define dout_prefix *_dout << "librbd::operation::ResizeRequest: " << this \
+ << " " << __func__ << ": "
namespace librbd {
namespace operation {
void ResizeRequest<I>::send_pre_block_writes() {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << dendl;
+ ldout(cct, 5) << dendl;
image_ctx.io_work_queue->block_writes(create_context_callback<
ResizeRequest<I>, &ResizeRequest<I>::handle_pre_block_writes>(this));
Context *ResizeRequest<I>::handle_pre_block_writes(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result < 0) {
lderr(cct) << "failed to block writes: " << cpp_strerror(*result) << dendl;
CephContext *cct = image_ctx.cct;
if (m_new_size < m_original_size && !m_allow_shrink) {
- ldout(cct, 1) << " shrinking the image is not permitted" << dendl;
+ ldout(cct, 1) << "shrinking the image is not permitted" << dendl;
image_ctx.io_work_queue->unblock_writes();
this->async_complete(-EINVAL);
return nullptr;
return send_grow_object_map();
}
- ldout(cct, 5) << this << " " << __func__ << dendl;
+ ldout(cct, 5) << dendl;
return nullptr;
}
Context *ResizeRequest<I>::handle_append_op_event(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result < 0) {
lderr(cct) << "failed to commit journal entry: " << cpp_strerror(*result)
void ResizeRequest<I>::send_trim_image() {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << dendl;
+ ldout(cct, 5) << dendl;
RWLock::RLocker owner_locker(image_ctx.owner_lock);
TrimRequest<I> *req = TrimRequest<I>::create(
Context *ResizeRequest<I>::handle_trim_image(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result == -ERESTART) {
ldout(cct, 5) << "resize operation interrupted" << dendl;
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << dendl;
+ ldout(cct, 5) << dendl;
RWLock::RLocker owner_locker(image_ctx.owner_lock);
auto ctx = create_context_callback<
Context *ResizeRequest<I>::handle_flush_cache(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result < 0) {
lderr(cct) << "failed to flush cache: " << cpp_strerror(*result) << dendl;
void ResizeRequest<I>::send_invalidate_cache() {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << dendl;
+ ldout(cct, 5) << dendl;
// need to invalidate since we're deleting objects, and
// ObjectCacher doesn't track non-existent objects
Context *ResizeRequest<I>::handle_invalidate_cache(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
// ignore busy error -- writeback was successfully flushed so we might be
// wasting some cache space for trimmed objects, but they will get purged
RWLock::WLocker snap_locker(image_ctx.snap_lock);
m_shrink_size_visible = true;
}
- image_ctx.io_work_queue->unblock_writes();
if (m_original_size == m_new_size) {
+ image_ctx.io_work_queue->unblock_writes();
return this->create_context_finisher(0);
} else if (m_new_size < m_original_size) {
+ image_ctx.io_work_queue->unblock_writes();
send_flush_cache();
return nullptr;
}
image_ctx.snap_lock.put_read();
image_ctx.owner_lock.put_read();
- send_post_block_writes();
+ // IO is still blocked
+ send_update_header();
return nullptr;
}
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << dendl;
+ ldout(cct, 5) << dendl;
// should have been canceled prior to releasing lock
ceph_assert(image_ctx.exclusive_lock == nullptr ||
Context *ResizeRequest<I>::handle_grow_object_map(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result < 0) {
- lderr(cct) << this << " " << __func__ << ": failed to resize object map: "
+ lderr(cct) << "failed to resize object map: "
<< cpp_strerror(*result) << dendl;
+ image_ctx.io_work_queue->unblock_writes();
return this->create_context_finisher(*result);
}
- send_post_block_writes();
+ // IO is still blocked
+ send_update_header();
return nullptr;
}
}
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << " "
- << "original_size=" << m_original_size << ", "
+ ldout(cct, 5) << "original_size=" << m_original_size << ", "
<< "new_size=" << m_new_size << dendl;
// should have been canceled prior to releasing lock
Context *ResizeRequest<I>::handle_shrink_object_map(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result < 0) {
- lderr(cct) << this << " " << __func__ << ": failed to resize object map: "
+ lderr(cct) << "failed to resize object map: "
<< cpp_strerror(*result) << dendl;
image_ctx.io_work_queue->unblock_writes();
return this->create_context_finisher(*result);
void ResizeRequest<I>::send_post_block_writes() {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << dendl;
+ ldout(cct, 5) << dendl;
RWLock::RLocker owner_locker(image_ctx.owner_lock);
image_ctx.io_work_queue->block_writes(create_context_callback<
Context *ResizeRequest<I>::handle_post_block_writes(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result < 0) {
image_ctx.io_work_queue->unblock_writes();
void ResizeRequest<I>::send_update_header() {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << " "
- << "original_size=" << m_original_size << ", "
+ ldout(cct, 5) << "original_size=" << m_original_size << ", "
<< "new_size=" << m_new_size << dendl;;
// should have been canceled prior to releasing lock
Context *ResizeRequest<I>::handle_update_header(int *result) {
I &image_ctx = this->m_image_ctx;
CephContext *cct = image_ctx.cct;
- ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
+ ldout(cct, 5) << "r=" << *result << dendl;
if (*result < 0) {
lderr(cct) << "failed to update image header: " << cpp_strerror(*result)
}
}
- // blocked by POST_BLOCK_WRITES state
+ // blocked by PRE_BLOCK_WRITES (grow) or POST_BLOCK_WRITES (shrink) state
image_ctx.io_work_queue->unblock_writes();
}
InSequence seq;
expect_block_writes(mock_image_ctx, 0);
expect_append_op_event(mock_image_ctx, true, 0);
- expect_unblock_writes(mock_image_ctx);
expect_grow_object_map(mock_image_ctx);
- expect_block_writes(mock_image_ctx, 0);
expect_update_header(mock_image_ctx, 0);
expect_unblock_writes(mock_image_ctx);
expect_commit_op_event(mock_image_ctx, 0);
expect_block_writes(mock_image_ctx, 0);
expect_append_op_event(mock_image_ctx, true, 0);
expect_unblock_writes(mock_image_ctx);
- expect_grow_object_map(mock_image_ctx);
+
+ MockTrimRequest mock_trim_request;
+ auto mock_io_image_dispatch_spec = new MockIoImageDispatchSpec();
+ expect_flush_cache(mock_image_ctx, *mock_io_image_dispatch_spec, 0);
+ expect_invalidate_cache(mock_image_ctx, 0);
+ expect_trim(mock_image_ctx, mock_trim_request, 0);
expect_block_writes(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
expect_commit_op_event(mock_image_ctx, -EINVAL);
- ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size * 2, true, 0, false));
+ ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, true, 0,
+ false));
}
TEST_F(TestMockOperationResizeRequest, UpdateHeaderError) {
InSequence seq;
expect_block_writes(mock_image_ctx, 0);
expect_append_op_event(mock_image_ctx, true, 0);
- expect_unblock_writes(mock_image_ctx);
expect_grow_object_map(mock_image_ctx);
- expect_block_writes(mock_image_ctx, 0);
expect_update_header(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
expect_commit_op_event(mock_image_ctx, -EINVAL);