From: Heinz Mauelshagen <heinzm@xxxxxxxxxx> 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@xxxxxxxxxx> --- drivers/md/dm-raid.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) 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"; -- 2.41.0 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/dm-devel