aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c94
1 files changed, 64 insertions, 30 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index d4351ff0849f..180949e94a7b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1487,37 +1487,76 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
1487 1487
1488static LIST_HEAD(pending_raid_disks); 1488static LIST_HEAD(pending_raid_disks);
1489 1489
1490static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev) 1490/*
1491 * Try to register data integrity profile for an mddev
1492 *
1493 * This is called when an array is started and after a disk has been kicked
1494 * from the array. It only succeeds if all working and active component devices
1495 * are integrity capable with matching profiles.
1496 */
1497int md_integrity_register(mddev_t *mddev)
1498{
1499 mdk_rdev_t *rdev, *reference = NULL;
1500
1501 if (list_empty(&mddev->disks))
1502 return 0; /* nothing to do */
1503 if (blk_get_integrity(mddev->gendisk))
1504 return 0; /* already registered */
1505 list_for_each_entry(rdev, &mddev->disks, same_set) {
1506 /* skip spares and non-functional disks */
1507 if (test_bit(Faulty, &rdev->flags))
1508 continue;
1509 if (rdev->raid_disk < 0)
1510 continue;
1511 /*
1512 * If at least one rdev is not integrity capable, we can not
1513 * enable data integrity for the md device.
1514 */
1515 if (!bdev_get_integrity(rdev->bdev))
1516 return -EINVAL;
1517 if (!reference) {
1518 /* Use the first rdev as the reference */
1519 reference = rdev;
1520 continue;
1521 }
1522 /* does this rdev's profile match the reference profile? */
1523 if (blk_integrity_compare(reference->bdev->bd_disk,
1524 rdev->bdev->bd_disk) < 0)
1525 return -EINVAL;
1526 }
1527 /*
1528 * All component devices are integrity capable and have matching
1529 * profiles, register the common profile for the md device.
1530 */
1531 if (blk_integrity_register(mddev->gendisk,
1532 bdev_get_integrity(reference->bdev)) != 0) {
1533 printk(KERN_ERR "md: failed to register integrity for %s\n",
1534 mdname(mddev));
1535 return -EINVAL;
1536 }
1537 printk(KERN_NOTICE "md: data integrity on %s enabled\n",
1538 mdname(mddev));
1539 return 0;
1540}
1541EXPORT_SYMBOL(md_integrity_register);
1542
1543/* Disable data integrity if non-capable/non-matching disk is being added */
1544void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
1491{ 1545{
1492 struct mdk_personality *pers = mddev->pers;
1493 struct gendisk *disk = mddev->gendisk;
1494 struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev); 1546 struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
1495 struct blk_integrity *bi_mddev = blk_get_integrity(disk); 1547 struct blk_integrity *bi_mddev = blk_get_integrity(mddev->gendisk);
1496 1548
1497 /* Data integrity passthrough not supported on RAID 4, 5 and 6 */ 1549 if (!bi_mddev) /* nothing to do */
1498 if (pers && pers->level >= 4 && pers->level <= 6)
1499 return; 1550 return;
1500 1551 if (rdev->raid_disk < 0) /* skip spares */
1501 /* If rdev is integrity capable, register profile for mddev */
1502 if (!bi_mddev && bi_rdev) {
1503 if (blk_integrity_register(disk, bi_rdev))
1504 printk(KERN_ERR "%s: %s Could not register integrity!\n",
1505 __func__, disk->disk_name);
1506 else
1507 printk(KERN_NOTICE "Enabling data integrity on %s\n",
1508 disk->disk_name);
1509 return; 1552 return;
1510 } 1553 if (bi_rdev && blk_integrity_compare(mddev->gendisk,
1511 1554 rdev->bdev->bd_disk) >= 0)
1512 /* Check that mddev and rdev have matching profiles */ 1555 return;
1513 if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) { 1556 printk(KERN_NOTICE "disabling data integrity on %s\n", mdname(mddev));
1514 printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__, 1557 blk_integrity_unregister(mddev->gendisk);
1515 disk->disk_name, rdev->bdev->bd_disk->disk_name);
1516 printk(KERN_NOTICE "Disabling data integrity on %s\n",
1517 disk->disk_name);
1518 blk_integrity_unregister(disk);
1519 }
1520} 1558}
1559EXPORT_SYMBOL(md_integrity_add_rdev);
1521 1560
1522static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) 1561static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1523{ 1562{
@@ -1591,7 +1630,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1591 /* May as well allow recovery to be retried once */ 1630 /* May as well allow recovery to be retried once */
1592 mddev->recovery_disabled = 0; 1631 mddev->recovery_disabled = 0;
1593 1632
1594 md_integrity_check(rdev, mddev);
1595 return 0; 1633 return 0;
1596 1634
1597 fail: 1635 fail:
@@ -4048,10 +4086,6 @@ static int do_md_run(mddev_t * mddev)
4048 } 4086 }
4049 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); 4087 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
4050 4088
4051 if (pers->level >= 4 && pers->level <= 6)
4052 /* Cannot support integrity (yet) */
4053 blk_integrity_unregister(mddev->gendisk);
4054
4055 if (mddev->reshape_position != MaxSector && 4089 if (mddev->reshape_position != MaxSector &&
4056 pers->start_reshape == NULL) { 4090 pers->start_reshape == NULL) {
4057 /* This personality cannot handle reshaping... */ 4091 /* This personality cannot handle reshaping... */