From 0bb0c10500ba634216238c40e1eeddce92b4d488 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Mon, 27 Mar 2017 10:51:33 -0700 Subject: [PATCH] md/raid5: use consistency_policy to remove journal feature When journal device of an array fails, the array is forced into read-only mode. To make the array normal without adding another journal device, we need to remove journal _feature_ from the array. This patch allows remove journal _feature_ from an array, For journal existing journal should be either missing or faulty. To remove journal feature, it is necessary to remove the journal device first: mdadm --fail /dev/md0 /dev/sdb mdadm: set /dev/sdb faulty in /dev/md0 mdadm --remove /dev/md0 /dev/sdb mdadm: hot removed /dev/sdb from /dev/md0 Then the journal feature can be removed by echoing into the sysfs file: cat /sys/block/md0/md/consistency_policy journal echo resync > /sys/block/md0/md/consistency_policy cat /sys/block/md0/md/consistency_policy resync Signed-off-by: Song Liu Signed-off-by: Shaohua Li --- drivers/md/raid5.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 266d661dc69b64..6036d5e41ddd86 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -8292,17 +8292,41 @@ static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf) } if (strncmp(buf, "ppl", 3) == 0 && !raid5_has_ppl(conf)) { - mddev_suspend(mddev); - set_bit(MD_HAS_PPL, &mddev->flags); - err = log_init(conf, NULL); - if (!err) + /* ppl only works with RAID 5 */ + if (conf->level == 5) { + mddev_suspend(mddev); + set_bit(MD_HAS_PPL, &mddev->flags); + err = log_init(conf, NULL); + if (!err) + raid5_reset_stripe_cache(mddev); + mddev_resume(mddev); + } else + err = -EINVAL; + } else if (strncmp(buf, "resync", 6) == 0) { + if (raid5_has_ppl(conf)) { + mddev_suspend(mddev); + log_exit(conf); raid5_reset_stripe_cache(mddev); - mddev_resume(mddev); - } else if (strncmp(buf, "resync", 6) == 0 && raid5_has_ppl(conf)) { - mddev_suspend(mddev); - log_exit(conf); - raid5_reset_stripe_cache(mddev); - mddev_resume(mddev); + mddev_resume(mddev); + } else if (test_bit(MD_HAS_JOURNAL, &conf->mddev->flags) && + r5l_log_disk_error(conf)) { + bool journal_dev_exists = false; + struct md_rdev *rdev; + + rdev_for_each(rdev, mddev) + if (test_bit(Journal, &rdev->flags)) { + journal_dev_exists = true; + break; + } + + if (!journal_dev_exists) { + mddev_suspend(mddev); + clear_bit(MD_HAS_JOURNAL, &mddev->flags); + mddev_resume(mddev); + } else /* need remove journal device first */ + err = -EBUSY; + } else + err = -EINVAL; } else { err = -EINVAL; } @@ -8337,6 +8361,7 @@ static struct md_personality raid6_personality = .quiesce = raid5_quiesce, .takeover = raid6_takeover, .congested = raid5_congested, + .change_consistency_policy = raid5_change_consistency_policy, }; static struct md_personality raid5_personality = { @@ -8385,6 +8410,7 @@ static struct md_personality raid4_personality = .quiesce = raid5_quiesce, .takeover = raid4_takeover, .congested = raid5_congested, + .change_consistency_policy = raid5_change_consistency_policy, }; static int __init raid5_init(void)