On 02/28/2017 02:31 AM, Shaohua Li wrote: > On Tue, Feb 21, 2017 at 08:44:01PM +0100, Artur Paszkiewicz wrote: >> Allow writing to 'consistency_policy' attribute when the array is >> active. Add a new function 'change_consistency_policy' to the >> md_personality operations structure to handle the change in the >> personality code. Values "ppl" and "resync" are accepted and >> turn PPL on and off respectively. >> >> When enabling PPL its location and size should first be set using >> 'ppl_sector' and 'ppl_size' attributes and a valid PPL header should be >> written at this location on each member device. >> >> Enabling or disabling PPL is performed under a suspended array. The >> raid5_reset_stripe_cache function frees the stripe cache and allocates >> it again in order to allocate or free the ppl_pages for the stripes in >> the stripe cache. >> >> Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@xxxxxxxxx> >> --- >> drivers/md/md.c | 12 ++++++++--- >> drivers/md/md.h | 2 ++ >> drivers/md/raid5-ppl.c | 4 ++++ >> drivers/md/raid5.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ >> 4 files changed, 73 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/md/md.c b/drivers/md/md.c >> index 3ff979d538d4..b70e19513588 100644 >> --- a/drivers/md/md.c >> +++ b/drivers/md/md.c >> @@ -5003,14 +5003,20 @@ consistency_policy_show(struct mddev *mddev, char *page) >> static ssize_t >> consistency_policy_store(struct mddev *mddev, const char *buf, size_t len) >> { >> + int err = 0; >> + >> if (mddev->pers) { >> - return -EBUSY; >> + if (mddev->pers->change_consistency_policy) >> + err = mddev->pers->change_consistency_policy(mddev, buf); >> + else >> + err = -EBUSY; >> } else if (mddev->external && strncmp(buf, "ppl", 3) == 0) { >> set_bit(MD_HAS_PPL, &mddev->flags); >> - return len; >> } else { >> - return -EINVAL; >> + err = -EINVAL; >> } >> + >> + return err ? err : len; >> } >> >> static struct md_sysfs_entry md_consistency_policy = >> diff --git a/drivers/md/md.h b/drivers/md/md.h >> index 66a5a16e79f7..88a5155c152e 100644 >> --- a/drivers/md/md.h >> +++ b/drivers/md/md.h >> @@ -548,6 +548,8 @@ struct md_personality >> /* congested implements bdi.congested_fn(). >> * Will not be called while array is 'suspended' */ >> int (*congested)(struct mddev *mddev, int bits); >> + /* Changes the consistency policy of an active array. */ >> + int (*change_consistency_policy)(struct mddev *mddev, const char *buf); >> }; >> >> struct md_sysfs_entry { >> diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c >> index c2070d124849..a5c4d3333bce 100644 >> --- a/drivers/md/raid5-ppl.c >> +++ b/drivers/md/raid5-ppl.c >> @@ -1095,6 +1095,10 @@ int ppl_init_log(struct r5conf *conf) >> */ >> mddev->recovery_cp = MaxSector; >> set_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags); >> + } else if (mddev->pers && ppl_conf->mismatch_count > 0) { >> + /* no mismatch allowed when enabling PPL for a running array */ >> + ret = -EINVAL; >> + goto err; >> } >> >> conf->ppl = ppl_conf; >> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c >> index b17e90f06f19..754fb8e1c76f 100644 >> --- a/drivers/md/raid5.c >> +++ b/drivers/md/raid5.c >> @@ -8319,6 +8319,63 @@ static void *raid6_takeover(struct mddev *mddev) >> return setup_conf(mddev); >> } >> >> +static void raid5_reset_stripe_cache(struct mddev *mddev) >> +{ >> + struct r5conf *conf = mddev->private; >> + >> + mutex_lock(&conf->cache_size_mutex); >> + while (conf->max_nr_stripes && >> + drop_one_stripe(conf)) >> + ; >> + while (conf->min_nr_stripes > conf->max_nr_stripes && >> + grow_one_stripe(conf, GFP_KERNEL)) >> + ; >> + mutex_unlock(&conf->cache_size_mutex); >> +} >> + >> +static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf) >> +{ >> + struct r5conf *conf; >> + int err; >> + >> + err = mddev_lock(mddev); >> + if (err) >> + return err; >> + conf = mddev->private; >> + if (!conf) { >> + mddev_unlock(mddev); >> + return -ENODEV; >> + } >> + >> + if (strncmp(buf, "ppl", 3) == 0 && >> + !test_bit(MD_HAS_PPL, &mddev->flags)) { >> + mddev_suspend(mddev); >> + err = ppl_init_log(conf); > > I didn't see you check if all rdev have valid ppl setting in ppl_load. Am I > missing anything? Is it possible some rdevs have ppl set, but some not. In the > case, we should just bail out. All rdevs should have valid ppl settings, this is checked in ppl_validate_rdev(), just before ppl_load() is called. > Also check if this is raid5 pers->change_consistency_policy is only set for raid5_personality, so it is (currently) not necessary. Thanks, Artur -- To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html