From 2f464b8e8235efe2c5d972cf8054dcc2010b100e Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 14 Aug 2024 17:42:44 +0200 Subject: [PATCH 04/32] drbd: fix exposed_uuid going backward When a diskless node in the primary role creates a new current UUID, it sends it all its UpToDate peers and sets it as its own exposed UUID. If there is only one UpToDate node in the secondary role and it sends its current UUID to the diskless primary at about the same time, then with the following state change, through the function ensure_expose_data_uuid(), the diskless primary sets its exposed_uuid back to the previous one. Avoid this problem by not accepting a current_uuid update from a peer when I am primary (authoritative), and I have told the peer the latest update, and that peer is already on that latest (authoritative) value. --- drbd/drbd_main.c | 1 + drbd/drbd_receiver.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drbd/drbd_main.c b/drbd/drbd_main.c index 862438885f35..bc3283b045c9 100644 --- a/drbd/drbd_main.c +++ b/drbd/drbd_main.c @@ -1484,6 +1484,7 @@ int drbd_send_current_uuid(struct drbd_peer_device *peer_device, u64 current_uui if (!p) return -EIO; + peer_device->comm_current_uuid = current_uuid; p->uuid = cpu_to_be64(current_uuid); p->weak_nodes = cpu_to_be64(weak_nodes); return drbd_send_command(peer_device, P_CURRENT_UUID, DATA_STREAM); diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c index ee54cf3ac116..985fac8e69b3 100644 --- a/drbd/drbd_receiver.c +++ b/drbd/drbd_receiver.c @@ -5815,7 +5815,15 @@ static int receive_uuids110(struct drbd_connection *connection, struct packet_in peer_md = device->ldev->md.peers; spin_lock_irq(&device->ldev->md.uuid_lock); } - peer_device->current_uuid = be64_to_cpu(p->current_uuid); + + if (device->resource->role[NOW] != R_PRIMARY || + device->disk_state[NOW] != D_DISKLESS || + (peer_device->current_uuid & ~UUID_PRIMARY) != + (device->exposed_data_uuid & ~UUID_PRIMARY) || + (peer_device->comm_current_uuid & ~UUID_PRIMARY) != + (device->exposed_data_uuid & ~UUID_PRIMARY)) + peer_device->current_uuid = be64_to_cpu(p->current_uuid); + peer_device->dirty_bits = be64_to_cpu(p->dirty_bits); peer_device->uuid_flags = be64_to_cpu(p->uuid_flags); if (peer_device->uuid_flags & UUID_FLAG_HAS_UNALLOC) { -- 2.35.3