drivers/block/drbd/drbd_main.c | 3 --- drivers/block/drbd/drbd_nl.c | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-)
DRBD requires stable pages because it may read the same bio data
multiple times for local disk I/O and network transmission, and in
some cases for calculating checksums.
The BLK_FEAT_STABLE_WRITES flag is set when the device is first
created, but blk_set_stacking_limits() clears it whenever a
backing device is attached. In some cases the flag may be
inherited from the backing device, but we want it to be enabled
at all times.
Unconditionally re-enable BLK_FEAT_STABLE_WRITES in
drbd_reconsider_queue_parameters() after the queue parameter
negotiations.
Also, document why we want this flag enabled in the first place.
Fixes: 1a02f3a73f8c ("block: move the stable_writes flag to queue_limits")
Signed-off-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com>
---
Note: this commit is based on the for-6.19/block tree in case it is
still possible to take it into the 6.19 release as this *could* lead
to silent data corruption. However, due to other protection
mechanisms in DRBD, this is relatively unlikely to happen in the
real world and we have not seen any corresponding reports from users.
So if this only lands in 6.20/7.0, it is also fine.
drivers/block/drbd/drbd_main.c | 3 ---
drivers/block/drbd/drbd_nl.c | 20 +++++++++++++++++++-
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index c73376886e7a..1f6ac9202b66 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2659,9 +2659,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
* connect.
*/
.max_hw_sectors = DRBD_MAX_BIO_SIZE_SAFE >> 8,
- .features = BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA |
- BLK_FEAT_ROTATIONAL |
- BLK_FEAT_STABLE_WRITES,
};
device = minor_to_device(minor);
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index 91f3b8afb63c..b502038be0a9 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1296,6 +1296,8 @@ void drbd_reconsider_queue_parameters(struct drbd_device *device,
lim.max_segments = drbd_backing_dev_max_segments(device);
} else {
lim.max_segments = BLK_MAX_SEGMENTS;
+ lim.features = BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA |
+ BLK_FEAT_ROTATIONAL | BLK_FEAT_STABLE_WRITES;
}
lim.max_hw_sectors = new >> SECTOR_SHIFT;
@@ -1318,8 +1320,24 @@ void drbd_reconsider_queue_parameters(struct drbd_device *device,
lim.max_hw_discard_sectors = 0;
}
- if (bdev)
+ if (bdev) {
blk_stack_limits(&lim, &b->limits, 0);
+ /*
+ * blk_set_stacking_limits() cleared the features, and
+ * blk_stack_limits() may or may not have inherited
+ * BLK_FEAT_STABLE_WRITES from the backing device.
+ *
+ * DRBD always requires stable writes because:
+ * 1. The same bio data is read for both local disk I/O and
+ * network transmission. If the page changes mid-flight,
+ * the local and remote copies could diverge.
+ * 2. When data integrity is enabled, DRBD calculates a
+ * checksum before sending the data. If the page changes
+ * between checksum calculation and transmission, the
+ * receiver will detect a checksum mismatch.
+ */
+ lim.features |= BLK_FEAT_STABLE_WRITES;
+ }
/*
* If we can handle "zeroes" efficiently on the protocol, we want to do
base-commit: b1e5c96ab4a011763afac033f6660cf1eb499458
--
2.52.0
On Thu, Feb 05, 2026 at 06:39:29PM +0100, Christoph Böhmwalder wrote: > DRBD requires stable pages because it may read the same bio data > multiple times for local disk I/O and network transmission, and in > some cases for calculating checksums. > > The BLK_FEAT_STABLE_WRITES flag is set when the device is first > created, but blk_set_stacking_limits() clears it whenever a > backing device is attached. In some cases the flag may be > inherited from the backing device, but we want it to be enabled > at all times. This looks like a bug. If an underlying device requires BLK_FEAT_STABLE_WRITES, the upper device needs to inherit it. > Note: this commit is based on the for-6.19/block tree in case it is > still possible to take it into the 6.19 release as this *could* lead > to silent data corruption. However, due to other protection > mechanisms in DRBD, this is relatively unlikely to happen in the > real world and we have not seen any corresponding reports from users. > So if this only lands in 6.20/7.0, it is also fine. I'm fine with this as a hot fix for 6.19 and -stable: Reviewed-by: Christoph Hellwig <hch@lst.de> But can you please also do the proper block layer fix and then revert the drbd one?
© 2016 - 2026 Red Hat, Inc.