diff options
author | David S. Miller <davem@davemloft.net> | 2009-08-12 20:44:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-12 20:44:53 -0400 |
commit | aa11d958d1a6572eda08214d7c6a735804fe48a5 (patch) | |
tree | d025b05270ad1e010660d17eeadc6ac3c1abbd7d /drivers/md/md.c | |
parent | 07f6642ee9418e962e54cbc07471cfe2e559c568 (diff) | |
parent | 9799218ae36910af50f002a5db1802d576fffb43 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
arch/microblaze/include/asm/socket.h
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 162 |
1 files changed, 99 insertions, 63 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 0f4a70c43ffc..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 | ||
1488 | static LIST_HEAD(pending_raid_disks); | 1499 | static LIST_HEAD(pending_raid_disks); |
1489 | 1500 | ||
1490 | static 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 | */ | ||
1508 | int 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 | } | ||
1552 | EXPORT_SYMBOL(md_integrity_register); | ||
1553 | |||
1554 | /* Disable data integrity if non-capable/non-matching disk is being added */ | ||
1555 | void 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 | } |
1570 | EXPORT_SYMBOL(md_integrity_add_rdev); | ||
1521 | 1571 | ||
1522 | static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | 1572 | static 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: |
@@ -1756,9 +1805,10 @@ static void print_sb_1(struct mdp_superblock_1 *sb) | |||
1756 | __u8 *uuid; | 1805 | __u8 *uuid; |
1757 | 1806 | ||
1758 | uuid = sb->set_uuid; | 1807 | uuid = sb->set_uuid; |
1759 | printk(KERN_INFO "md: SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x" | 1808 | printk(KERN_INFO |
1760 | ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n" | 1809 | "md: SB: (V:%u) (F:0x%08x) Array-ID:<%02x%02x%02x%02x" |
1761 | KERN_INFO "md: Name: \"%s\" CT:%llu\n", | 1810 | ":%02x%02x:%02x%02x:%02x%02x:%02x%02x%02x%02x%02x%02x>\n" |
1811 | "md: Name: \"%s\" CT:%llu\n", | ||
1762 | le32_to_cpu(sb->major_version), | 1812 | le32_to_cpu(sb->major_version), |
1763 | le32_to_cpu(sb->feature_map), | 1813 | le32_to_cpu(sb->feature_map), |
1764 | uuid[0], uuid[1], uuid[2], uuid[3], | 1814 | uuid[0], uuid[1], uuid[2], uuid[3], |
@@ -1770,12 +1820,13 @@ static void print_sb_1(struct mdp_superblock_1 *sb) | |||
1770 | & MD_SUPERBLOCK_1_TIME_SEC_MASK); | 1820 | & MD_SUPERBLOCK_1_TIME_SEC_MASK); |
1771 | 1821 | ||
1772 | uuid = sb->device_uuid; | 1822 | uuid = sb->device_uuid; |
1773 | printk(KERN_INFO "md: L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu" | 1823 | printk(KERN_INFO |
1824 | "md: L%u SZ%llu RD:%u LO:%u CS:%u DO:%llu DS:%llu SO:%llu" | ||
1774 | " RO:%llu\n" | 1825 | " RO:%llu\n" |
1775 | KERN_INFO "md: Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x" | 1826 | "md: Dev:%08x UUID: %02x%02x%02x%02x:%02x%02x:%02x%02x:%02x%02x" |
1776 | ":%02x%02x%02x%02x%02x%02x\n" | 1827 | ":%02x%02x%02x%02x%02x%02x\n" |
1777 | KERN_INFO "md: (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n" | 1828 | "md: (F:0x%08x) UT:%llu Events:%llu ResyncOffset:%llu CSUM:0x%08x\n" |
1778 | KERN_INFO "md: (MaxDev:%u) \n", | 1829 | "md: (MaxDev:%u) \n", |
1779 | le32_to_cpu(sb->level), | 1830 | le32_to_cpu(sb->level), |
1780 | (unsigned long long)le64_to_cpu(sb->size), | 1831 | (unsigned long long)le64_to_cpu(sb->size), |
1781 | le32_to_cpu(sb->raid_disks), | 1832 | le32_to_cpu(sb->raid_disks), |
@@ -2655,6 +2706,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) | |||
2655 | ssize_t rv = len; | 2706 | ssize_t rv = len; |
2656 | struct mdk_personality *pers; | 2707 | struct mdk_personality *pers; |
2657 | void *priv; | 2708 | void *priv; |
2709 | mdk_rdev_t *rdev; | ||
2658 | 2710 | ||
2659 | if (mddev->pers == NULL) { | 2711 | if (mddev->pers == NULL) { |
2660 | if (len == 0) | 2712 | if (len == 0) |
@@ -2734,6 +2786,12 @@ level_store(mddev_t *mddev, const char *buf, size_t len) | |||
2734 | mddev_suspend(mddev); | 2786 | mddev_suspend(mddev); |
2735 | mddev->pers->stop(mddev); | 2787 | mddev->pers->stop(mddev); |
2736 | 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 | } | ||
2737 | mddev->pers = pers; | 2795 | mddev->pers = pers; |
2738 | mddev->private = priv; | 2796 | mddev->private = priv; |
2739 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); | 2797 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); |
@@ -3683,17 +3741,8 @@ array_size_store(mddev_t *mddev, const char *buf, size_t len) | |||
3683 | 3741 | ||
3684 | mddev->array_sectors = sectors; | 3742 | mddev->array_sectors = sectors; |
3685 | set_capacity(mddev->gendisk, mddev->array_sectors); | 3743 | set_capacity(mddev->gendisk, mddev->array_sectors); |
3686 | if (mddev->pers) { | 3744 | if (mddev->pers) |
3687 | struct block_device *bdev = bdget_disk(mddev->gendisk, 0); | 3745 | revalidate_disk(mddev->gendisk); |
3688 | |||
3689 | if (bdev) { | ||
3690 | mutex_lock(&bdev->bd_inode->i_mutex); | ||
3691 | i_size_write(bdev->bd_inode, | ||
3692 | (loff_t)mddev->array_sectors << 9); | ||
3693 | mutex_unlock(&bdev->bd_inode->i_mutex); | ||
3694 | bdput(bdev); | ||
3695 | } | ||
3696 | } | ||
3697 | 3746 | ||
3698 | return len; | 3747 | return len; |
3699 | } | 3748 | } |
@@ -4046,10 +4095,6 @@ static int do_md_run(mddev_t * mddev) | |||
4046 | } | 4095 | } |
4047 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); | 4096 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); |
4048 | 4097 | ||
4049 | if (pers->level >= 4 && pers->level <= 6) | ||
4050 | /* Cannot support integrity (yet) */ | ||
4051 | blk_integrity_unregister(mddev->gendisk); | ||
4052 | |||
4053 | if (mddev->reshape_position != MaxSector && | 4098 | if (mddev->reshape_position != MaxSector && |
4054 | pers->start_reshape == NULL) { | 4099 | pers->start_reshape == NULL) { |
4055 | /* This personality cannot handle reshaping... */ | 4100 | /* This personality cannot handle reshaping... */ |
@@ -4187,6 +4232,7 @@ static int do_md_run(mddev_t * mddev) | |||
4187 | md_wakeup_thread(mddev->thread); | 4232 | md_wakeup_thread(mddev->thread); |
4188 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ | 4233 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ |
4189 | 4234 | ||
4235 | revalidate_disk(mddev->gendisk); | ||
4190 | mddev->changed = 1; | 4236 | mddev->changed = 1; |
4191 | md_new_event(mddev); | 4237 | md_new_event(mddev); |
4192 | sysfs_notify_dirent(mddev->sysfs_state); | 4238 | sysfs_notify_dirent(mddev->sysfs_state); |
@@ -5085,18 +5131,8 @@ static int update_size(mddev_t *mddev, sector_t num_sectors) | |||
5085 | return -ENOSPC; | 5131 | return -ENOSPC; |
5086 | } | 5132 | } |
5087 | rv = mddev->pers->resize(mddev, num_sectors); | 5133 | rv = mddev->pers->resize(mddev, num_sectors); |
5088 | if (!rv) { | 5134 | if (!rv) |
5089 | struct block_device *bdev; | 5135 | revalidate_disk(mddev->gendisk); |
5090 | |||
5091 | bdev = bdget_disk(mddev->gendisk, 0); | ||
5092 | if (bdev) { | ||
5093 | mutex_lock(&bdev->bd_inode->i_mutex); | ||
5094 | i_size_write(bdev->bd_inode, | ||
5095 | (loff_t)mddev->array_sectors << 9); | ||
5096 | mutex_unlock(&bdev->bd_inode->i_mutex); | ||
5097 | bdput(bdev); | ||
5098 | } | ||
5099 | } | ||
5100 | return rv; | 5136 | return rv; |
5101 | } | 5137 | } |
5102 | 5138 | ||