diff options
author | Song Liu <songliubraving@fb.com> | 2017-03-27 10:51:33 -0700 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2017-03-27 12:02:33 -0700 |
commit | 0bb0c10500ba634216238c40e1eeddce92b4d488 (patch) | |
tree | f7bca55d0d048f27362a6d65a2ef3be6eb70b1e6 /drivers/md/raid5.c | |
parent | 1ad45a9bc4e0cd5a6e6fb0e6c5d35d6c87f14c76 (diff) | |
download | lwn-0bb0c10500ba634216238c40e1eeddce92b4d488.tar.gz lwn-0bb0c10500ba634216238c40e1eeddce92b4d488.zip |
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 <songliubraving@fb.com>
Signed-off-by: Shaohua Li <shli@fb.com>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 266d661dc69b..6036d5e41ddd 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) |