[PATCH] drbd: serialize UUID snapshot in drbd_md_write()

Ziyu Zhang ziyuzhang201 at gmail.com
Mon May 4 05:25:50 CEST 2026


drbd_md_write() copies device->ldev->md.uuid[] into the on-disk
metadata block without holding uuid_lock.

The write-side helpers drbd_uuid_new_current() and drbd_uuid_set_bm()
update md.uuid[] under uuid_lock, and some updates span multiple UUID
slots as one logical state transition. An unlocked drbd_md_write() can
therefore observe and persist a mixed UUID tuple assembled from two
different states.

This is problematic because the serialized UUID tuple is written to
stable storage and later consumed by reconnect and resync decision
logic, meaning an inconsistent on-disk snapshot can represent a state that
never existed atomically in memory.

Protect the UUID copy with uuid_lock so drbd_md_write() serializes one
coherent snapshot.

Fixes: b411b3637fa7 ("The DRBD driver")
Signed-off-by: Ziyu Zhang <ziyuzhang201 at gmail.com>
---
 drivers/block/drbd/drbd_main.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index a9e49b212..6f835dd05 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -3004,13 +3004,17 @@ void drbd_md_write(struct drbd_device *device, void *b)
 {
 	struct meta_data_on_disk *buffer = b;
 	sector_t sector;
+	unsigned long flags;
 	int i;
 
 	memset(buffer, 0, sizeof(*buffer));
 
 	buffer->la_size_sect = cpu_to_be64(get_capacity(device->vdisk));
+	/* Serialize the UUID tuple as one coherent snapshot. */
+	spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
 	for (i = UI_CURRENT; i < UI_SIZE; i++)
 		buffer->uuid[i] = cpu_to_be64(device->ldev->md.uuid[i]);
+	spin_unlock_irqrestore(&device->ldev->md.uuid_lock, flags);
 	buffer->flags = cpu_to_be32(device->ldev->md.flags);
 	buffer->magic = cpu_to_be32(DRBD_MD_MAGIC_84_UNCLEAN);
 
-- 
2.43.0



More information about the drbd-dev mailing list