diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 8e221a20f5d9..5404b2295820 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -848,7 +848,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | |||
848 | bio->bi_end_io = super_written; | 848 | bio->bi_end_io = super_written; |
849 | 849 | ||
850 | atomic_inc(&mddev->pending_writes); | 850 | atomic_inc(&mddev->pending_writes); |
851 | submit_bio(REQ_WRITE | REQ_SYNC | REQ_FLUSH | REQ_FUA, bio); | 851 | submit_bio(WRITE_FLUSH_FUA, bio); |
852 | } | 852 | } |
853 | 853 | ||
854 | void md_super_wait(mddev_t *mddev) | 854 | void md_super_wait(mddev_t *mddev) |
@@ -1138,8 +1138,11 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version | |||
1138 | ret = 0; | 1138 | ret = 0; |
1139 | } | 1139 | } |
1140 | rdev->sectors = rdev->sb_start; | 1140 | rdev->sectors = rdev->sb_start; |
1141 | /* Limit to 4TB as metadata cannot record more than that */ | ||
1142 | if (rdev->sectors >= (2ULL << 32)) | ||
1143 | rdev->sectors = (2ULL << 32) - 2; | ||
1141 | 1144 | ||
1142 | if (rdev->sectors < sb->size * 2 && sb->level > 1) | 1145 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) |
1143 | /* "this cannot possibly happen" ... */ | 1146 | /* "this cannot possibly happen" ... */ |
1144 | ret = -EINVAL; | 1147 | ret = -EINVAL; |
1145 | 1148 | ||
@@ -1173,7 +1176,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1173 | mddev->clevel[0] = 0; | 1176 | mddev->clevel[0] = 0; |
1174 | mddev->layout = sb->layout; | 1177 | mddev->layout = sb->layout; |
1175 | mddev->raid_disks = sb->raid_disks; | 1178 | mddev->raid_disks = sb->raid_disks; |
1176 | mddev->dev_sectors = sb->size * 2; | 1179 | mddev->dev_sectors = ((sector_t)sb->size) * 2; |
1177 | mddev->events = ev1; | 1180 | mddev->events = ev1; |
1178 | mddev->bitmap_info.offset = 0; | 1181 | mddev->bitmap_info.offset = 0; |
1179 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; | 1182 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; |
@@ -1415,6 +1418,11 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | |||
1415 | rdev->sb_start = calc_dev_sboffset(rdev); | 1418 | rdev->sb_start = calc_dev_sboffset(rdev); |
1416 | if (!num_sectors || num_sectors > rdev->sb_start) | 1419 | if (!num_sectors || num_sectors > rdev->sb_start) |
1417 | num_sectors = rdev->sb_start; | 1420 | num_sectors = rdev->sb_start; |
1421 | /* Limit to 4TB as metadata cannot record more than that. | ||
1422 | * 4TB == 2^32 KB, or 2*2^32 sectors. | ||
1423 | */ | ||
1424 | if (num_sectors >= (2ULL << 32)) | ||
1425 | num_sectors = (2ULL << 32) - 2; | ||
1418 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1426 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
1419 | rdev->sb_page); | 1427 | rdev->sb_page); |
1420 | md_super_wait(rdev->mddev); | 1428 | md_super_wait(rdev->mddev); |
@@ -1738,6 +1746,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1738 | sb->level = cpu_to_le32(mddev->level); | 1746 | sb->level = cpu_to_le32(mddev->level); |
1739 | sb->layout = cpu_to_le32(mddev->layout); | 1747 | sb->layout = cpu_to_le32(mddev->layout); |
1740 | 1748 | ||
1749 | if (test_bit(WriteMostly, &rdev->flags)) | ||
1750 | sb->devflags |= WriteMostly1; | ||
1751 | else | ||
1752 | sb->devflags &= ~WriteMostly1; | ||
1753 | |||
1741 | if (mddev->bitmap && mddev->bitmap_info.file == NULL) { | 1754 | if (mddev->bitmap && mddev->bitmap_info.file == NULL) { |
1742 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); | 1755 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); |
1743 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); | 1756 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); |
@@ -2561,7 +2574,10 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2561 | int err = -EINVAL; | 2574 | int err = -EINVAL; |
2562 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { | 2575 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { |
2563 | md_error(rdev->mddev, rdev); | 2576 | md_error(rdev->mddev, rdev); |
2564 | err = 0; | 2577 | if (test_bit(Faulty, &rdev->flags)) |
2578 | err = 0; | ||
2579 | else | ||
2580 | err = -EBUSY; | ||
2565 | } else if (cmd_match(buf, "remove")) { | 2581 | } else if (cmd_match(buf, "remove")) { |
2566 | if (rdev->raid_disk >= 0) | 2582 | if (rdev->raid_disk >= 0) |
2567 | err = -EBUSY; | 2583 | err = -EBUSY; |
@@ -2584,7 +2600,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2584 | err = 0; | 2600 | err = 0; |
2585 | } else if (cmd_match(buf, "-blocked")) { | 2601 | } else if (cmd_match(buf, "-blocked")) { |
2586 | if (!test_bit(Faulty, &rdev->flags) && | 2602 | if (!test_bit(Faulty, &rdev->flags) && |
2587 | test_bit(BlockedBadBlocks, &rdev->flags)) { | 2603 | rdev->badblocks.unacked_exist) { |
2588 | /* metadata handler doesn't understand badblocks, | 2604 | /* metadata handler doesn't understand badblocks, |
2589 | * so we need to fail the device | 2605 | * so we need to fail the device |
2590 | */ | 2606 | */ |
@@ -5983,6 +5999,8 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev) | |||
5983 | return -ENODEV; | 5999 | return -ENODEV; |
5984 | 6000 | ||
5985 | md_error(mddev, rdev); | 6001 | md_error(mddev, rdev); |
6002 | if (!test_bit(Faulty, &rdev->flags)) | ||
6003 | return -EBUSY; | ||
5986 | return 0; | 6004 | return 0; |
5987 | } | 6005 | } |
5988 | 6006 | ||