Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bb0c105 authored by Song Liu's avatar Song Liu Committed by Shaohua Li
Browse files

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: default avatarSong Liu <songliubraving@fb.com>
Signed-off-by: default avatarShaohua Li <shli@fb.com>
parent 1ad45a9b
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -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)) {
		/* 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 if (strncmp(buf, "resync", 6) == 0 && raid5_has_ppl(conf)) {
		} 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 (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)