Skip to content

Commit

Permalink
Merge pull request #10055: jewel: Whitelist EBUSY error from snap unp…
Browse files Browse the repository at this point in the history
…rotect for journal replay

Reviewed-by: Loic Dachary <ldachary@redhat.com>
  • Loading branch information
Loic Dachary committed Aug 8, 2016
2 parents 2da5a87 + 757babb commit 54755ae
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/librbd/journal/Replay.cc
Expand Up @@ -108,24 +108,29 @@ struct C_RefreshIfRequired : public Context {
C_RefreshIfRequired(I &image_ctx, Context *on_finish)
: image_ctx(image_ctx), on_finish(on_finish) {
}
virtual ~C_RefreshIfRequired() {
delete on_finish;
}

virtual void finish(int r) override {
CephContext *cct = image_ctx.cct;
Context *ctx = on_finish;
on_finish = nullptr;

if (r < 0) {
lderr(cct) << "C_RefreshIfRequired: " << __func__ << ": r=" << r << dendl;
image_ctx.op_work_queue->queue(on_finish, r);
image_ctx.op_work_queue->queue(ctx, r);
return;
}

if (image_ctx.state->is_refresh_required()) {
ldout(cct, 20) << "C_RefreshIfRequired: " << __func__ << ": "
<< "refresh required" << dendl;
image_ctx.state->refresh(on_finish);
image_ctx.state->refresh(ctx);
return;
}

image_ctx.op_work_queue->queue(on_finish, 0);
image_ctx.op_work_queue->queue(ctx, 0);
}
};

Expand Down Expand Up @@ -340,6 +345,7 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
<< "op_tid=" << event.op_tid << dendl;

bool op_in_progress;
bool filter_ret_val;
Context *on_op_complete = nullptr;
Context *on_op_finish_event = nullptr;
{
Expand All @@ -360,6 +366,10 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
op_in_progress = op_event.op_in_progress;
std::swap(on_op_complete, op_event.on_op_complete);
std::swap(on_op_finish_event, op_event.on_op_finish_event);

// special errors which indicate op never started but was recorded
// as failed in the journal
filter_ret_val = (op_event.op_finish_error_codes.count(event.r) != 0);
}

if (event.r < 0) {
Expand All @@ -373,7 +383,7 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
// creating the op event
delete on_op_complete;
delete on_op_finish_event;
handle_op_complete(event.op_tid, event.r);
handle_op_complete(event.op_tid, filter_ret_val ? 0 : event.r);
}
return;
}
Expand Down Expand Up @@ -503,6 +513,9 @@ void Replay<I>::handle_event(const journal::SnapUnprotectEvent &event,
event,
on_op_complete));

// ignore errors recorded in the journal
op_event->op_finish_error_codes = {-EBUSY};

// ignore errors caused due to replay
op_event->ignore_error_codes = {-EINVAL};

Expand Down
1 change: 1 addition & 0 deletions src/librbd/journal/Replay.h
Expand Up @@ -52,6 +52,7 @@ class Replay {
Context *on_finish_ready = nullptr;
Context *on_finish_safe = nullptr;
Context *on_op_complete = nullptr;
ReturnValues op_finish_error_codes;
ReturnValues ignore_error_codes;
};

Expand Down
28 changes: 28 additions & 0 deletions src/test/librbd/journal/test_mock_Replay.cc
Expand Up @@ -972,6 +972,34 @@ TEST_F(TestMockJournalReplay, SnapUnprotectEvent) {
ASSERT_EQ(0, on_finish_safe.wait());
}

TEST_F(TestMockJournalReplay, SnapUnprotectOpFinishBusy) {
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);

librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));

MockReplayImageCtx mock_image_ctx(*ictx);
MockJournalReplay mock_journal_replay(mock_image_ctx);
expect_op_work_queue(mock_image_ctx);

InSequence seq;
C_SaferCond on_start_ready;
C_SaferCond on_start_safe;
when_process(mock_journal_replay, EventEntry{SnapUnprotectEvent(123, "snap")},
&on_start_ready, &on_start_safe);
ASSERT_EQ(0, on_start_ready.wait());

// aborts the snap unprotect op if image had children
C_SaferCond on_finish_ready;
C_SaferCond on_finish_safe;
when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EBUSY)},
&on_finish_ready, &on_finish_safe);

ASSERT_EQ(0, on_start_safe.wait());
ASSERT_EQ(0, on_finish_safe.wait());
ASSERT_EQ(0, on_finish_ready.wait());
}

TEST_F(TestMockJournalReplay, SnapUnprotectEventInvalid) {
REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);

Expand Down

0 comments on commit 54755ae

Please sign in to comment.