diff mbox series

dm raid: writebehind for raid1 fails to apply and is falsely set

Message ID be1b9883fdc1e91f0b05d2092c7179f4331c18a1.1692021777.git.heinzm@redhat.com (mailing list archive)
State New, archived
Headers show
Series dm raid: writebehind for raid1 fails to apply and is falsely set | expand

Commit Message

Heinz Mauelshagen Aug. 14, 2023, 2:05 p.m. UTC
From: Heinz Mauelshagen <heinzm@redhat.com>

Call chain md_run() -> md_bitmap_create() in the target's constructor reads the bitmap
superblock thus overwriting any set rs->md.bitmap_info.max_write_behind.  In order to
make such set writebehind value persistent, save/restore its value around the md_run() call.

As the MD bitmap code uses the writebehind numeral as the maximum number of delayed writes
to any writemostly component device(s) in a RAID1 array, avoid falsely dividing it by 2 and
correct comment accordingly.

Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com>
---
 drivers/md/dm-raid.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index becdb689190e..32d55210ea0c 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -1111,7 +1111,7 @@  static int validate_raid_redundancy(struct raid_set *rs)
  *    [min_recovery_rate <kB/sec/disk>]	Throttle RAID initialization
  *    [max_recovery_rate <kB/sec/disk>]	Throttle RAID initialization
  *    [write_mostly <idx>]		Indicate a write mostly drive via index
- *    [max_write_behind <sectors>]	See '-write-behind=' (man mdadm)
+ *    [max_write_behind <#writes>]	See '--write-behind=' (man mdadm)
  *    [stripe_cache <sectors>]		Stripe cache size for higher RAIDs
  *    [region_size <sectors>]		Defines granularity of bitmap
  *    [journal_dev <dev>]		raid4/5/6 journaling deviice
@@ -1349,16 +1349,13 @@  static int parse_raid_params(struct raid_set *rs, struct dm_arg_set *as,
 				return -EINVAL;
 			}
 
-			/*
-			 * In device-mapper, we specify things in sectors, but
-			 * MD records this value in kB
-			 */
-			if (value < 0 || value / 2 > COUNTER_MAX) {
+			/* Check for MD maximum.  */
+			if (!__within_range(value, 0, COUNTER_MAX)) {
 				rs->ti->error = "Max write-behind limit out of range";
 				return -EINVAL;
 			}
 
-			rs->md.bitmap_info.max_write_behind = value / 2;
+			rs->md.bitmap_info.max_write_behind = value;
 		} else if (!strcasecmp(key, dm_raid_arg_name_by_flag(CTR_FLAG_DAEMON_SLEEP))) {
 			if (test_and_set_bit(__CTR_FLAG_DAEMON_SLEEP, &rs->ctr_flags)) {
 				rs->ti->error = "Only one daemon_sleep argument pair allowed";
@@ -2997,6 +2994,7 @@  static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	bool resize = false;
 	struct raid_type *rt;
 	unsigned int num_raid_params, num_raid_devs;
+	unsigned long max_write_behind;
 	sector_t sb_array_sectors, rdev_sectors, reshape_sectors;
 	struct raid_set *rs = NULL;
 	const char *arg;
@@ -3238,6 +3236,10 @@  static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	/* Keep array frozen until resume. */
 	set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
 
+	/* Memorize max_write_behind as it does not stick in md_bitmap_create() */
+	if (test_bit(__CTR_FLAG_MAX_WRITE_BEHIND, &rs->ctr_flags))
+		max_write_behind = rs->md.bitmap_info.max_write_behind;
+
 	/* Has to be held on running the array */
 	mddev_lock_nointr(&rs->md);
 	r = md_run(&rs->md);
@@ -3248,6 +3250,10 @@  static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 		goto bad;
 	}
 
+	/* Now define max_write_behind. */
+	if (test_bit(__CTR_FLAG_MAX_WRITE_BEHIND, &rs->ctr_flags))
+		rs->md.bitmap_info.max_write_behind = max_write_behind;
+
 	r = md_start(&rs->md);
 	if (r) {
 		ti->error = "Failed to start raid array";