Skip to content

Commit ba903a3

Browse files
apaszkieshligit
authored andcommitted
raid5-ppl: runtime PPL enabling or disabling
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 <[email protected]> Signed-off-by: Shaohua Li <[email protected]>
1 parent 6358c23 commit ba903a3

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

drivers/md/md.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4996,14 +4996,20 @@ consistency_policy_show(struct mddev *mddev, char *page)
49964996
static ssize_t
49974997
consistency_policy_store(struct mddev *mddev, const char *buf, size_t len)
49984998
{
4999+
int err = 0;
5000+
49995001
if (mddev->pers) {
5000-
return -EBUSY;
5002+
if (mddev->pers->change_consistency_policy)
5003+
err = mddev->pers->change_consistency_policy(mddev, buf);
5004+
else
5005+
err = -EBUSY;
50015006
} else if (mddev->external && strncmp(buf, "ppl", 3) == 0) {
50025007
set_bit(MD_HAS_PPL, &mddev->flags);
5003-
return len;
50045008
} else {
5005-
return -EINVAL;
5009+
err = -EINVAL;
50065010
}
5011+
5012+
return err ? err : len;
50075013
}
50085014

50095015
static struct md_sysfs_entry md_consistency_policy =

drivers/md/md.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@ struct md_personality
545545
/* congested implements bdi.congested_fn().
546546
* Will not be called while array is 'suspended' */
547547
int (*congested)(struct mddev *mddev, int bits);
548+
/* Changes the consistency policy of an active array. */
549+
int (*change_consistency_policy)(struct mddev *mddev, const char *buf);
548550
};
549551

550552
struct md_sysfs_entry {

drivers/md/raid5-ppl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,10 @@ int ppl_init_log(struct r5conf *conf)
11871187
*/
11881188
mddev->recovery_cp = MaxSector;
11891189
set_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags);
1190+
} else if (mddev->pers && ppl_conf->mismatch_count > 0) {
1191+
/* no mismatch allowed when enabling PPL for a running array */
1192+
ret = -EINVAL;
1193+
goto err;
11901194
}
11911195

11921196
conf->log_private = ppl_conf;

drivers/md/raid5.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8334,6 +8334,58 @@ static void *raid6_takeover(struct mddev *mddev)
83348334
return setup_conf(mddev);
83358335
}
83368336

8337+
static void raid5_reset_stripe_cache(struct mddev *mddev)
8338+
{
8339+
struct r5conf *conf = mddev->private;
8340+
8341+
mutex_lock(&conf->cache_size_mutex);
8342+
while (conf->max_nr_stripes &&
8343+
drop_one_stripe(conf))
8344+
;
8345+
while (conf->min_nr_stripes > conf->max_nr_stripes &&
8346+
grow_one_stripe(conf, GFP_KERNEL))
8347+
;
8348+
mutex_unlock(&conf->cache_size_mutex);
8349+
}
8350+
8351+
static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf)
8352+
{
8353+
struct r5conf *conf;
8354+
int err;
8355+
8356+
err = mddev_lock(mddev);
8357+
if (err)
8358+
return err;
8359+
conf = mddev->private;
8360+
if (!conf) {
8361+
mddev_unlock(mddev);
8362+
return -ENODEV;
8363+
}
8364+
8365+
if (strncmp(buf, "ppl", 3) == 0 && !raid5_has_ppl(conf)) {
8366+
mddev_suspend(mddev);
8367+
set_bit(MD_HAS_PPL, &mddev->flags);
8368+
err = log_init(conf, NULL);
8369+
if (!err)
8370+
raid5_reset_stripe_cache(mddev);
8371+
mddev_resume(mddev);
8372+
} else if (strncmp(buf, "resync", 6) == 0 && raid5_has_ppl(conf)) {
8373+
mddev_suspend(mddev);
8374+
log_exit(conf);
8375+
raid5_reset_stripe_cache(mddev);
8376+
mddev_resume(mddev);
8377+
} else {
8378+
err = -EINVAL;
8379+
}
8380+
8381+
if (!err)
8382+
md_update_sb(mddev, 1);
8383+
8384+
mddev_unlock(mddev);
8385+
8386+
return err;
8387+
}
8388+
83378389
static struct md_personality raid6_personality =
83388390
{
83398391
.name = "raid6",
@@ -8379,6 +8431,7 @@ static struct md_personality raid5_personality =
83798431
.quiesce = raid5_quiesce,
83808432
.takeover = raid5_takeover,
83818433
.congested = raid5_congested,
8434+
.change_consistency_policy = raid5_change_consistency_policy,
83828435
};
83838436

83848437
static struct md_personality raid4_personality =

0 commit comments

Comments
 (0)