|
@@ -1438,6 +1438,38 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
|
|
|
|
|
|
static LIST_HEAD(pending_raid_disks);
|
|
|
|
|
|
+static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
|
|
|
+{
|
|
|
+ struct mdk_personality *pers = mddev->pers;
|
|
|
+ struct gendisk *disk = mddev->gendisk;
|
|
|
+ struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
|
|
|
+ struct blk_integrity *bi_mddev = blk_get_integrity(disk);
|
|
|
+
|
|
|
+ /* Data integrity passthrough not supported on RAID 4, 5 and 6 */
|
|
|
+ if (pers && pers->level >= 4 && pers->level <= 6)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* If rdev is integrity capable, register profile for mddev */
|
|
|
+ if (!bi_mddev && bi_rdev) {
|
|
|
+ if (blk_integrity_register(disk, bi_rdev))
|
|
|
+ printk(KERN_ERR "%s: %s Could not register integrity!\n",
|
|
|
+ __func__, disk->disk_name);
|
|
|
+ else
|
|
|
+ printk(KERN_NOTICE "Enabling data integrity on %s\n",
|
|
|
+ disk->disk_name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check that mddev and rdev have matching profiles */
|
|
|
+ if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
|
|
|
+ printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
|
|
|
+ disk->disk_name, rdev->bdev->bd_disk->disk_name);
|
|
|
+ printk(KERN_NOTICE "Disabling data integrity on %s\n",
|
|
|
+ disk->disk_name);
|
|
|
+ blk_integrity_unregister(disk);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
|
|
|
{
|
|
|
char b[BDEVNAME_SIZE];
|
|
@@ -1508,6 +1540,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
|
|
|
|
|
|
/* May as well allow recovery to be retried once */
|
|
|
mddev->recovery_disabled = 0;
|
|
|
+
|
|
|
+ md_integrity_check(rdev, mddev);
|
|
|
return 0;
|
|
|
|
|
|
fail:
|
|
@@ -3794,6 +3828,10 @@ static int do_md_run(mddev_t * mddev)
|
|
|
mddev->level = pers->level;
|
|
|
strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
|
|
|
|
|
|
+ if (pers->level >= 4 && pers->level <= 6)
|
|
|
+ /* Cannot support integrity (yet) */
|
|
|
+ blk_integrity_unregister(mddev->gendisk);
|
|
|
+
|
|
|
if (mddev->reshape_position != MaxSector &&
|
|
|
pers->start_reshape == NULL) {
|
|
|
/* This personality cannot handle reshaping... */
|
|
@@ -4129,6 +4167,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
|
|
|
printk(KERN_INFO "md: %s switched to read-only mode.\n",
|
|
|
mdname(mddev));
|
|
|
err = 0;
|
|
|
+ blk_integrity_unregister(disk);
|
|
|
md_new_event(mddev);
|
|
|
sysfs_notify_dirent(mddev->sysfs_state);
|
|
|
out:
|