aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-08-12 22:48:01 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-08-12 22:48:01 -0400
commite290861f99131fc42d98012a9ea2dc185f08f8f9 (patch)
tree5c8b92d095d74d03b281711c81bac54bd59989cd /drivers/md/md.c
parentb4a757367d36cebddcd332a4024d92f1e87af370 (diff)
parentdbefd606a3b3634799b625f4900336e61c89e868 (diff)
Merge branch 'sh/stable-updates'
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c144
1 files changed, 89 insertions, 55 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index d4351ff0849f..5b98bea4ff9b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1308,7 +1308,12 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
1308 } 1308 }
1309 if (mddev->level != LEVEL_MULTIPATH) { 1309 if (mddev->level != LEVEL_MULTIPATH) {
1310 int role; 1310 int role;
1311 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); 1311 if (rdev->desc_nr < 0 ||
1312 rdev->desc_nr >= le32_to_cpu(sb->max_dev)) {
1313 role = 0xffff;
1314 rdev->desc_nr = -1;
1315 } else
1316 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
1312 switch(role) { 1317 switch(role) {
1313 case 0xffff: /* spare */ 1318 case 0xffff: /* spare */
1314 break; 1319 break;
@@ -1394,8 +1399,14 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1394 if (rdev2->desc_nr+1 > max_dev) 1399 if (rdev2->desc_nr+1 > max_dev)
1395 max_dev = rdev2->desc_nr+1; 1400 max_dev = rdev2->desc_nr+1;
1396 1401
1397 if (max_dev > le32_to_cpu(sb->max_dev)) 1402 if (max_dev > le32_to_cpu(sb->max_dev)) {
1403 int bmask;
1398 sb->max_dev = cpu_to_le32(max_dev); 1404 sb->max_dev = cpu_to_le32(max_dev);
1405 rdev->sb_size = max_dev * 2 + 256;
1406 bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1;
1407 if (rdev->sb_size & bmask)
1408 rdev->sb_size = (rdev->sb_size | bmask) + 1;
1409 }
1399 for (i=0; i<max_dev;i++) 1410 for (i=0; i<max_dev;i++)
1400 sb->dev_roles[i] = cpu_to_le16(0xfffe); 1411 sb->dev_roles[i] = cpu_to_le16(0xfffe);
1401 1412
@@ -1487,37 +1498,76 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
1487 1498
1488static LIST_HEAD(pending_raid_disks); 1499static LIST_HEAD(pending_raid_disks);
1489 1500
1490static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev) 1501/*
1502 * Try to register data integrity profile for an mddev
1503 *
1504 * This is called when an array is started and after a disk has been kicked
1505 * from the array. It only succeeds if all working and active component devices
1506 * are integrity capable with matching profiles.
1507 */
1508int md_integrity_register(mddev_t *mddev)
1509{
1510 mdk_rdev_t *rdev, *reference = NULL;
1511
1512 if (list_empty(&mddev->disks))
1513 return 0; /* nothing to do */
1514 if (blk_get_integrity(mddev->gendisk))
1515 return 0; /* already registered */
1516 list_for_each_entry(rdev, &mddev->disks, same_set) {
1517 /* skip spares and non-functional disks */
1518 if (test_bit(Faulty, &rdev->flags))
1519 continue;
1520 if (rdev->raid_disk < 0)
1521 continue;
1522 /*
1523 * If at least one rdev is not integrity capable, we can not
1524 * enable data integrity for the md device.
1525 */
1526 if (!bdev_get_integrity(rdev->bdev))
1527 return -EINVAL;
1528 if (!reference) {
1529 /* Use the first rdev as the reference */
1530 reference = rdev;
1531 continue;
1532 }
1533 /* does this rdev's profile match the reference profile? */
1534 if (blk_integrity_compare(reference->bdev->bd_disk,
1535 rdev->bdev->bd_disk) < 0)
1536 return -EINVAL;
1537 }
1538 /*
1539 * All component devices are integrity capable and have matching
1540 * profiles, register the common profile for the md device.
1541 */
1542 if (blk_integrity_register(mddev->gendisk,
1543 bdev_get_integrity(reference->bdev)) != 0) {
1544 printk(KERN_ERR "md: failed to register integrity for %s\n",
1545 mdname(mddev));
1546 return -EINVAL;
1547 }
1548 printk(KERN_NOTICE "md: data integrity on %s enabled\n",
1549 mdname(mddev));
1550 return 0;
1551}
1552EXPORT_SYMBOL(md_integrity_register);
1553
1554/* Disable data integrity if non-capable/non-matching disk is being added */
1555void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
1491{ 1556{
1492 struct mdk_personality *pers = mddev->pers;
1493 struct gendisk *disk = mddev->gendisk;
1494 struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev); 1557 struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
1495 struct blk_integrity *bi_mddev = blk_get_integrity(disk); 1558 struct blk_integrity *bi_mddev = blk_get_integrity(mddev->gendisk);
1496 1559
1497 /* Data integrity passthrough not supported on RAID 4, 5 and 6 */ 1560 if (!bi_mddev) /* nothing to do */
1498 if (pers && pers->level >= 4 && pers->level <= 6)
1499 return; 1561 return;
1500 1562 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; 1563 return;
1510 } 1564 if (bi_rdev && blk_integrity_compare(mddev->gendisk,
1511 1565 rdev->bdev->bd_disk) >= 0)
1512 /* Check that mddev and rdev have matching profiles */ 1566 return;
1513 if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) { 1567 printk(KERN_NOTICE "disabling data integrity on %s\n", mdname(mddev));
1514 printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__, 1568 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} 1569}
1570EXPORT_SYMBOL(md_integrity_add_rdev);
1521 1571
1522static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) 1572static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1523{ 1573{
@@ -1591,7 +1641,6 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1591 /* May as well allow recovery to be retried once */ 1641 /* May as well allow recovery to be retried once */
1592 mddev->recovery_disabled = 0; 1642 mddev->recovery_disabled = 0;
1593 1643
1594 md_integrity_check(rdev, mddev);
1595 return 0; 1644 return 0;
1596 1645
1597 fail: 1646 fail:
@@ -2657,6 +2706,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len)
2657 ssize_t rv = len; 2706 ssize_t rv = len;
2658 struct mdk_personality *pers; 2707 struct mdk_personality *pers;
2659 void *priv; 2708 void *priv;
2709 mdk_rdev_t *rdev;
2660 2710
2661 if (mddev->pers == NULL) { 2711 if (mddev->pers == NULL) {
2662 if (len == 0) 2712 if (len == 0)
@@ -2736,6 +2786,12 @@ level_store(mddev_t *mddev, const char *buf, size_t len)
2736 mddev_suspend(mddev); 2786 mddev_suspend(mddev);
2737 mddev->pers->stop(mddev); 2787 mddev->pers->stop(mddev);
2738 module_put(mddev->pers->owner); 2788 module_put(mddev->pers->owner);
2789 /* Invalidate devices that are now superfluous */
2790 list_for_each_entry(rdev, &mddev->disks, same_set)
2791 if (rdev->raid_disk >= mddev->raid_disks) {
2792 rdev->raid_disk = -1;
2793 clear_bit(In_sync, &rdev->flags);
2794 }
2739 mddev->pers = pers; 2795 mddev->pers = pers;
2740 mddev->private = priv; 2796 mddev->private = priv;
2741 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); 2797 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
@@ -3685,17 +3741,8 @@ array_size_store(mddev_t *mddev, const char *buf, size_t len)
3685 3741
3686 mddev->array_sectors = sectors; 3742 mddev->array_sectors = sectors;
3687 set_capacity(mddev->gendisk, mddev->array_sectors); 3743 set_capacity(mddev->gendisk, mddev->array_sectors);
3688 if (mddev->pers) { 3744 if (mddev->pers)
3689 struct block_device *bdev = bdget_disk(mddev->gendisk, 0); 3745 revalidate_disk(mddev->gendisk);
3690
3691 if (bdev) {
3692 mutex_lock(&bdev->bd_inode->i_mutex);
3693 i_size_write(bdev->bd_inode,
3694 (loff_t)mddev->array_sectors << 9);
3695 mutex_unlock(&bdev->bd_inode->i_mutex);
3696 bdput(bdev);
3697 }
3698 }
3699 3746
3700 return len; 3747 return len;
3701} 3748}
@@ -4048,10 +4095,6 @@ static int do_md_run(mddev_t * mddev)
4048 } 4095 }
4049 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); 4096 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
4050 4097
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 && 4098 if (mddev->reshape_position != MaxSector &&
4056 pers->start_reshape == NULL) { 4099 pers->start_reshape == NULL) {
4057 /* This personality cannot handle reshaping... */ 4100 /* This personality cannot handle reshaping... */
@@ -4189,6 +4232,7 @@ static int do_md_run(mddev_t * mddev)
4189 md_wakeup_thread(mddev->thread); 4232 md_wakeup_thread(mddev->thread);
4190 md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ 4233 md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
4191 4234
4235 revalidate_disk(mddev->gendisk);
4192 mddev->changed = 1; 4236 mddev->changed = 1;
4193 md_new_event(mddev); 4237 md_new_event(mddev);
4194 sysfs_notify_dirent(mddev->sysfs_state); 4238 sysfs_notify_dirent(mddev->sysfs_state);
@@ -5087,18 +5131,8 @@ static int update_size(mddev_t *mddev, sector_t num_sectors)
5087 return -ENOSPC; 5131 return -ENOSPC;
5088 } 5132 }
5089 rv = mddev->pers->resize(mddev, num_sectors); 5133 rv = mddev->pers->resize(mddev, num_sectors);
5090 if (!rv) { 5134 if (!rv)
5091 struct block_device *bdev; 5135 revalidate_disk(mddev->gendisk);
5092
5093 bdev = bdget_disk(mddev->gendisk, 0);
5094 if (bdev) {
5095 mutex_lock(&bdev->bd_inode->i_mutex);
5096 i_size_write(bdev->bd_inode,
5097 (loff_t)mddev->array_sectors << 9);
5098 mutex_unlock(&bdev->bd_inode->i_mutex);
5099 bdput(bdev);
5100 }
5101 }
5102 return rv; 5136 return rv;
5103} 5137}
5104 5138