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);