From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1424516AbcFMW1F (ORCPT ); Mon, 13 Jun 2016 18:27:05 -0400 Received: from zimbra13.linbit.com ([212.69.166.240]:36342 "EHLO zimbra13.linbit.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1424434AbcFMW0v (ORCPT ); Mon, 13 Jun 2016 18:26:51 -0400 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" From: Philipp Reisner To: Jens Axboe , linux-kernel@vger.kernel.org Cc: drbd-dev@lists.linbit.com Subject: [PATCH 25/30] drbd: bump current uuid when resuming IO with diskless peer Date: Tue, 14 Jun 2016 00:26:34 +0200 Message-Id: <1465856799-2151-26-git-send-email-philipp.reisner@linbit.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <575ECD32.2080700@fb.com> References: <575ECD32.2080700@fb.com> In-Reply-To: <575ECD32.2080700@fb.com> References: <575ECD32.2080700@fb.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lars Ellenberg Scenario, starting with normal operation Connected Primary/Secondary UpToDate/UpToDate NetworkFailure Primary/Unknown UpToDate/DUnknown (frozen) ... more failures happen, secondary loses it's disk, but eventually is able to re-establish the replication link ... Connected Primary/Secondary UpToDate/Diskless (resumed; needs to bump uuid!) We used to just resume/resent suspended requests, without bumping the UUID. Which will lead to problems later, when we want to re-attach the disk on the peer, without first disconnecting, or if we experience additional failures, because we now have diverging data without being able to recognize it. Make sure we also bump the current data generation UUID, if we notice "peer disk unknown" -> "peer disk known bad". Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_state.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index 7562c5c..a1b5e6c9 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -1637,6 +1637,26 @@ static void broadcast_state_change(struct drbd_state_change *state_change) #undef REMEMBER_STATE_CHANGE } +/* takes old and new peer disk state */ +static bool lost_contact_to_peer_data(enum drbd_disk_state os, enum drbd_disk_state ns) +{ + if ((os >= D_INCONSISTENT && os != D_UNKNOWN && os != D_OUTDATED) + && (ns < D_INCONSISTENT || ns == D_UNKNOWN || ns == D_OUTDATED)) + return true; + + /* Scenario, starting with normal operation + * Connected Primary/Secondary UpToDate/UpToDate + * NetworkFailure Primary/Unknown UpToDate/DUnknown (frozen) + * ... + * Connected Primary/Secondary UpToDate/Diskless (resumed; needs to bump uuid!) + */ + if (os == D_UNKNOWN + && (ns == D_DISKLESS || ns == D_FAILED || ns == D_OUTDATED)) + return true; + + return false; +} + /** * after_state_ch() - Perform after state change actions that may sleep * @device: DRBD device. @@ -1708,6 +1728,13 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, idr_for_each_entry(&connection->peer_devices, peer_device, vnr) clear_bit(NEW_CUR_UUID, &peer_device->device->flags); rcu_read_unlock(); + + /* We should actively create a new uuid, _before_ + * we resume/resent, if the peer is diskless + * (recovery from a multiple error scenario). + * Currently, this happens with a slight delay + * below when checking lost_contact_to_peer_data() ... + */ _tl_restart(connection, RESEND); _conn_request_state(connection, (union drbd_state) { { .susp_fen = 1 } }, @@ -1751,12 +1778,7 @@ static void after_state_ch(struct drbd_device *device, union drbd_state os, BM_LOCKED_TEST_ALLOWED); /* Lost contact to peer's copy of the data */ - if ((os.pdsk >= D_INCONSISTENT && - os.pdsk != D_UNKNOWN && - os.pdsk != D_OUTDATED) - && (ns.pdsk < D_INCONSISTENT || - ns.pdsk == D_UNKNOWN || - ns.pdsk == D_OUTDATED)) { + if (lost_contact_to_peer_data(os.pdsk, ns.pdsk)) { if (get_ldev(device)) { if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && device->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) { -- 2.7.4