File fix-replace-detached-device-wonot-sync.patch of Package drbd.16907

Fix possible data corruption after replace a detached device.
Back port upstream commit 9c77fe79db7c39bc56e58c85d02b0948b7457b31

diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c
index 15514763..9fd2477a 100644
--- a/drbd/drbd_nl.c
+++ b/drbd/drbd_nl.c
@@ -2773,6 +2773,12 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info)
 		struct drbd_connection *connection = peer_device->connection;
 		int bitmap_index;
 
+		if (peer_device->bitmap_index != -1) {
+			drbd_err(peer_device,
+					"ASSERTION FAILED bitmap_index %d during attach, expected -1\n",
+					peer_device->bitmap_index);
+		}
+
 		bitmap_index = nbc->md.peers[connection->peer_node_id].bitmap_index;
 		if (bitmap_index != -1)
 			peer_device->bitmap_index = bitmap_index;
diff --git a/drbd/drbd_req.c b/drbd/drbd_req.c
index 8b640b89..f382d13d 100644
--- a/drbd/drbd_req.c
+++ b/drbd/drbd_req.c
@@ -1172,6 +1172,7 @@ static bool drbd_may_do_local_read(struct drbd_device *device, sector_t sector,
 {
 	struct drbd_md *md = &device->ldev->md;
 	unsigned int node_id;
+	unsigned int n_checked = 0;
 
 	unsigned long sbnr, ebnr;
 	sector_t esector, nr_sectors;
@@ -1197,6 +1198,13 @@ static bool drbd_may_do_local_read(struct drbd_device *device, sector_t sector,
 
 		if (drbd_bm_count_bits(device, peer_md->bitmap_index, sbnr, ebnr))
 			return false;
+		++n_checked;
+	}
+	if (n_checked == 0) {
+		if (drbd_ratelimit()) {
+			drbd_err(device, "No valid bitmap slots found to check!\n");
+		}
+		return false;
 	}
 	return true;
 }
diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c
index 09a23802..66305206 100644
--- a/drbd/drbd_state.c
+++ b/drbd/drbd_state.c
@@ -2242,6 +2242,14 @@ static void finish_state_change(struct drbd_resource *resource, struct completio
 			BUG_ON(test_and_set_bit(HAVE_LDEV, &device->flags));
 		}
 
+		if (disk_state[OLD] != D_DISKLESS && disk_state[NEW] == D_DISKLESS) {
+			/* who knows if we are ever going to be attached again,
+			 * and whether that will be the same device, or a newly
+			 * initialized one. */
+			for_each_peer_device(peer_device, device)
+				peer_device->bitmap_index = -1;
+		}
+
 		if (disk_state[OLD] == D_ATTACHING && disk_state[NEW] >= D_NEGOTIATING)
 			drbd_info(device, "attached to current UUID: %016llX\n", device->ldev->md.current_uuid);
 
openSUSE Build Service is sponsored by