diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 370 |
1 files changed, 321 insertions, 49 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 01233d855eb2..1c2f9048e1ae 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -402,6 +402,7 @@ void mddev_resume(struct mddev *mddev) | |||
402 | wake_up(&mddev->sb_wait); | 402 | wake_up(&mddev->sb_wait); |
403 | mddev->pers->quiesce(mddev, 0); | 403 | mddev->pers->quiesce(mddev, 0); |
404 | 404 | ||
405 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
405 | md_wakeup_thread(mddev->thread); | 406 | md_wakeup_thread(mddev->thread); |
406 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ | 407 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ |
407 | } | 408 | } |
@@ -452,7 +453,7 @@ static void submit_flushes(struct work_struct *ws) | |||
452 | atomic_inc(&rdev->nr_pending); | 453 | atomic_inc(&rdev->nr_pending); |
453 | atomic_inc(&rdev->nr_pending); | 454 | atomic_inc(&rdev->nr_pending); |
454 | rcu_read_unlock(); | 455 | rcu_read_unlock(); |
455 | bi = bio_alloc_mddev(GFP_KERNEL, 0, mddev); | 456 | bi = bio_alloc_mddev(GFP_NOIO, 0, mddev); |
456 | bi->bi_end_io = md_end_flush; | 457 | bi->bi_end_io = md_end_flush; |
457 | bi->bi_private = rdev; | 458 | bi->bi_private = rdev; |
458 | bi->bi_bdev = rdev->bdev; | 459 | bi->bi_bdev = rdev->bdev; |
@@ -607,6 +608,7 @@ void mddev_init(struct mddev *mddev) | |||
607 | init_waitqueue_head(&mddev->sb_wait); | 608 | init_waitqueue_head(&mddev->sb_wait); |
608 | init_waitqueue_head(&mddev->recovery_wait); | 609 | init_waitqueue_head(&mddev->recovery_wait); |
609 | mddev->reshape_position = MaxSector; | 610 | mddev->reshape_position = MaxSector; |
611 | mddev->reshape_backwards = 0; | ||
610 | mddev->resync_min = 0; | 612 | mddev->resync_min = 0; |
611 | mddev->resync_max = MaxSector; | 613 | mddev->resync_max = MaxSector; |
612 | mddev->level = LEVEL_NONE; | 614 | mddev->level = LEVEL_NONE; |
@@ -802,7 +804,7 @@ static int alloc_disk_sb(struct md_rdev * rdev) | |||
802 | return 0; | 804 | return 0; |
803 | } | 805 | } |
804 | 806 | ||
805 | static void free_disk_sb(struct md_rdev * rdev) | 807 | void md_rdev_clear(struct md_rdev *rdev) |
806 | { | 808 | { |
807 | if (rdev->sb_page) { | 809 | if (rdev->sb_page) { |
808 | put_page(rdev->sb_page); | 810 | put_page(rdev->sb_page); |
@@ -815,8 +817,10 @@ static void free_disk_sb(struct md_rdev * rdev) | |||
815 | put_page(rdev->bb_page); | 817 | put_page(rdev->bb_page); |
816 | rdev->bb_page = NULL; | 818 | rdev->bb_page = NULL; |
817 | } | 819 | } |
820 | kfree(rdev->badblocks.page); | ||
821 | rdev->badblocks.page = NULL; | ||
818 | } | 822 | } |
819 | 823 | EXPORT_SYMBOL_GPL(md_rdev_clear); | |
820 | 824 | ||
821 | static void super_written(struct bio *bio, int error) | 825 | static void super_written(struct bio *bio, int error) |
822 | { | 826 | { |
@@ -887,6 +891,10 @@ int sync_page_io(struct md_rdev *rdev, sector_t sector, int size, | |||
887 | rdev->meta_bdev : rdev->bdev; | 891 | rdev->meta_bdev : rdev->bdev; |
888 | if (metadata_op) | 892 | if (metadata_op) |
889 | bio->bi_sector = sector + rdev->sb_start; | 893 | bio->bi_sector = sector + rdev->sb_start; |
894 | else if (rdev->mddev->reshape_position != MaxSector && | ||
895 | (rdev->mddev->reshape_backwards == | ||
896 | (sector >= rdev->mddev->reshape_position))) | ||
897 | bio->bi_sector = sector + rdev->new_data_offset; | ||
890 | else | 898 | else |
891 | bio->bi_sector = sector + rdev->data_offset; | 899 | bio->bi_sector = sector + rdev->data_offset; |
892 | bio_add_page(bio, page, size, 0); | 900 | bio_add_page(bio, page, size, 0); |
@@ -1034,12 +1042,17 @@ static unsigned int calc_sb_csum(mdp_super_t * sb) | |||
1034 | struct super_type { | 1042 | struct super_type { |
1035 | char *name; | 1043 | char *name; |
1036 | struct module *owner; | 1044 | struct module *owner; |
1037 | int (*load_super)(struct md_rdev *rdev, struct md_rdev *refdev, | 1045 | int (*load_super)(struct md_rdev *rdev, |
1046 | struct md_rdev *refdev, | ||
1038 | int minor_version); | 1047 | int minor_version); |
1039 | int (*validate_super)(struct mddev *mddev, struct md_rdev *rdev); | 1048 | int (*validate_super)(struct mddev *mddev, |
1040 | void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); | 1049 | struct md_rdev *rdev); |
1050 | void (*sync_super)(struct mddev *mddev, | ||
1051 | struct md_rdev *rdev); | ||
1041 | unsigned long long (*rdev_size_change)(struct md_rdev *rdev, | 1052 | unsigned long long (*rdev_size_change)(struct md_rdev *rdev, |
1042 | sector_t num_sectors); | 1053 | sector_t num_sectors); |
1054 | int (*allow_new_offset)(struct md_rdev *rdev, | ||
1055 | unsigned long long new_offset); | ||
1043 | }; | 1056 | }; |
1044 | 1057 | ||
1045 | /* | 1058 | /* |
@@ -1111,6 +1124,7 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor | |||
1111 | 1124 | ||
1112 | rdev->preferred_minor = sb->md_minor; | 1125 | rdev->preferred_minor = sb->md_minor; |
1113 | rdev->data_offset = 0; | 1126 | rdev->data_offset = 0; |
1127 | rdev->new_data_offset = 0; | ||
1114 | rdev->sb_size = MD_SB_BYTES; | 1128 | rdev->sb_size = MD_SB_BYTES; |
1115 | rdev->badblocks.shift = -1; | 1129 | rdev->badblocks.shift = -1; |
1116 | 1130 | ||
@@ -1184,7 +1198,11 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1184 | mddev->dev_sectors = ((sector_t)sb->size) * 2; | 1198 | mddev->dev_sectors = ((sector_t)sb->size) * 2; |
1185 | mddev->events = ev1; | 1199 | mddev->events = ev1; |
1186 | mddev->bitmap_info.offset = 0; | 1200 | mddev->bitmap_info.offset = 0; |
1201 | mddev->bitmap_info.space = 0; | ||
1202 | /* bitmap can use 60 K after the 4K superblocks */ | ||
1187 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; | 1203 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; |
1204 | mddev->bitmap_info.default_space = 64*2 - (MD_SB_BYTES >> 9); | ||
1205 | mddev->reshape_backwards = 0; | ||
1188 | 1206 | ||
1189 | if (mddev->minor_version >= 91) { | 1207 | if (mddev->minor_version >= 91) { |
1190 | mddev->reshape_position = sb->reshape_position; | 1208 | mddev->reshape_position = sb->reshape_position; |
@@ -1192,6 +1210,8 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1192 | mddev->new_level = sb->new_level; | 1210 | mddev->new_level = sb->new_level; |
1193 | mddev->new_layout = sb->new_layout; | 1211 | mddev->new_layout = sb->new_layout; |
1194 | mddev->new_chunk_sectors = sb->new_chunk >> 9; | 1212 | mddev->new_chunk_sectors = sb->new_chunk >> 9; |
1213 | if (mddev->delta_disks < 0) | ||
1214 | mddev->reshape_backwards = 1; | ||
1195 | } else { | 1215 | } else { |
1196 | mddev->reshape_position = MaxSector; | 1216 | mddev->reshape_position = MaxSector; |
1197 | mddev->delta_disks = 0; | 1217 | mddev->delta_disks = 0; |
@@ -1218,9 +1238,12 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1218 | mddev->max_disks = MD_SB_DISKS; | 1238 | mddev->max_disks = MD_SB_DISKS; |
1219 | 1239 | ||
1220 | if (sb->state & (1<<MD_SB_BITMAP_PRESENT) && | 1240 | if (sb->state & (1<<MD_SB_BITMAP_PRESENT) && |
1221 | mddev->bitmap_info.file == NULL) | 1241 | mddev->bitmap_info.file == NULL) { |
1222 | mddev->bitmap_info.offset = | 1242 | mddev->bitmap_info.offset = |
1223 | mddev->bitmap_info.default_offset; | 1243 | mddev->bitmap_info.default_offset; |
1244 | mddev->bitmap_info.space = | ||
1245 | mddev->bitmap_info.space; | ||
1246 | } | ||
1224 | 1247 | ||
1225 | } else if (mddev->pers == NULL) { | 1248 | } else if (mddev->pers == NULL) { |
1226 | /* Insist on good event counter while assembling, except | 1249 | /* Insist on good event counter while assembling, except |
@@ -1434,6 +1457,12 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
1434 | return num_sectors; | 1457 | return num_sectors; |
1435 | } | 1458 | } |
1436 | 1459 | ||
1460 | static int | ||
1461 | super_90_allow_new_offset(struct md_rdev *rdev, unsigned long long new_offset) | ||
1462 | { | ||
1463 | /* non-zero offset changes not possible with v0.90 */ | ||
1464 | return new_offset == 0; | ||
1465 | } | ||
1437 | 1466 | ||
1438 | /* | 1467 | /* |
1439 | * version 1 superblock | 1468 | * version 1 superblock |
@@ -1469,6 +1498,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ | |||
1469 | struct mdp_superblock_1 *sb; | 1498 | struct mdp_superblock_1 *sb; |
1470 | int ret; | 1499 | int ret; |
1471 | sector_t sb_start; | 1500 | sector_t sb_start; |
1501 | sector_t sectors; | ||
1472 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; | 1502 | char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; |
1473 | int bmask; | 1503 | int bmask; |
1474 | 1504 | ||
@@ -1523,9 +1553,18 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ | |||
1523 | bdevname(rdev->bdev,b)); | 1553 | bdevname(rdev->bdev,b)); |
1524 | return -EINVAL; | 1554 | return -EINVAL; |
1525 | } | 1555 | } |
1556 | if (sb->pad0 || | ||
1557 | sb->pad3[0] || | ||
1558 | memcmp(sb->pad3, sb->pad3+1, sizeof(sb->pad3) - sizeof(sb->pad3[1]))) | ||
1559 | /* Some padding is non-zero, might be a new feature */ | ||
1560 | return -EINVAL; | ||
1526 | 1561 | ||
1527 | rdev->preferred_minor = 0xffff; | 1562 | rdev->preferred_minor = 0xffff; |
1528 | rdev->data_offset = le64_to_cpu(sb->data_offset); | 1563 | rdev->data_offset = le64_to_cpu(sb->data_offset); |
1564 | rdev->new_data_offset = rdev->data_offset; | ||
1565 | if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE) && | ||
1566 | (le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) | ||
1567 | rdev->new_data_offset += (s32)le32_to_cpu(sb->new_offset); | ||
1529 | atomic_set(&rdev->corrected_errors, le32_to_cpu(sb->cnt_corrected_read)); | 1568 | atomic_set(&rdev->corrected_errors, le32_to_cpu(sb->cnt_corrected_read)); |
1530 | 1569 | ||
1531 | rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; | 1570 | rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; |
@@ -1536,6 +1575,9 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ | |||
1536 | if (minor_version | 1575 | if (minor_version |
1537 | && rdev->data_offset < sb_start + (rdev->sb_size/512)) | 1576 | && rdev->data_offset < sb_start + (rdev->sb_size/512)) |
1538 | return -EINVAL; | 1577 | return -EINVAL; |
1578 | if (minor_version | ||
1579 | && rdev->new_data_offset < sb_start + (rdev->sb_size/512)) | ||
1580 | return -EINVAL; | ||
1539 | 1581 | ||
1540 | if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) | 1582 | if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) |
1541 | rdev->desc_nr = -1; | 1583 | rdev->desc_nr = -1; |
@@ -1607,16 +1649,14 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ | |||
1607 | else | 1649 | else |
1608 | ret = 0; | 1650 | ret = 0; |
1609 | } | 1651 | } |
1610 | if (minor_version) | 1652 | if (minor_version) { |
1611 | rdev->sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - | 1653 | sectors = (i_size_read(rdev->bdev->bd_inode) >> 9); |
1612 | le64_to_cpu(sb->data_offset); | 1654 | sectors -= rdev->data_offset; |
1613 | else | 1655 | } else |
1614 | rdev->sectors = rdev->sb_start; | 1656 | sectors = rdev->sb_start; |
1615 | if (rdev->sectors < le64_to_cpu(sb->data_size)) | 1657 | if (sectors < le64_to_cpu(sb->data_size)) |
1616 | return -EINVAL; | 1658 | return -EINVAL; |
1617 | rdev->sectors = le64_to_cpu(sb->data_size); | 1659 | rdev->sectors = le64_to_cpu(sb->data_size); |
1618 | if (le64_to_cpu(sb->size) > rdev->sectors) | ||
1619 | return -EINVAL; | ||
1620 | return ret; | 1660 | return ret; |
1621 | } | 1661 | } |
1622 | 1662 | ||
@@ -1644,17 +1684,37 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1644 | mddev->dev_sectors = le64_to_cpu(sb->size); | 1684 | mddev->dev_sectors = le64_to_cpu(sb->size); |
1645 | mddev->events = ev1; | 1685 | mddev->events = ev1; |
1646 | mddev->bitmap_info.offset = 0; | 1686 | mddev->bitmap_info.offset = 0; |
1687 | mddev->bitmap_info.space = 0; | ||
1688 | /* Default location for bitmap is 1K after superblock | ||
1689 | * using 3K - total of 4K | ||
1690 | */ | ||
1647 | mddev->bitmap_info.default_offset = 1024 >> 9; | 1691 | mddev->bitmap_info.default_offset = 1024 >> 9; |
1648 | 1692 | mddev->bitmap_info.default_space = (4096-1024) >> 9; | |
1693 | mddev->reshape_backwards = 0; | ||
1694 | |||
1649 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); | 1695 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); |
1650 | memcpy(mddev->uuid, sb->set_uuid, 16); | 1696 | memcpy(mddev->uuid, sb->set_uuid, 16); |
1651 | 1697 | ||
1652 | mddev->max_disks = (4096-256)/2; | 1698 | mddev->max_disks = (4096-256)/2; |
1653 | 1699 | ||
1654 | if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) && | 1700 | if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) && |
1655 | mddev->bitmap_info.file == NULL ) | 1701 | mddev->bitmap_info.file == NULL) { |
1656 | mddev->bitmap_info.offset = | 1702 | mddev->bitmap_info.offset = |
1657 | (__s32)le32_to_cpu(sb->bitmap_offset); | 1703 | (__s32)le32_to_cpu(sb->bitmap_offset); |
1704 | /* Metadata doesn't record how much space is available. | ||
1705 | * For 1.0, we assume we can use up to the superblock | ||
1706 | * if before, else to 4K beyond superblock. | ||
1707 | * For others, assume no change is possible. | ||
1708 | */ | ||
1709 | if (mddev->minor_version > 0) | ||
1710 | mddev->bitmap_info.space = 0; | ||
1711 | else if (mddev->bitmap_info.offset > 0) | ||
1712 | mddev->bitmap_info.space = | ||
1713 | 8 - mddev->bitmap_info.offset; | ||
1714 | else | ||
1715 | mddev->bitmap_info.space = | ||
1716 | -mddev->bitmap_info.offset; | ||
1717 | } | ||
1658 | 1718 | ||
1659 | if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) { | 1719 | if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_RESHAPE_ACTIVE)) { |
1660 | mddev->reshape_position = le64_to_cpu(sb->reshape_position); | 1720 | mddev->reshape_position = le64_to_cpu(sb->reshape_position); |
@@ -1662,6 +1722,11 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1662 | mddev->new_level = le32_to_cpu(sb->new_level); | 1722 | mddev->new_level = le32_to_cpu(sb->new_level); |
1663 | mddev->new_layout = le32_to_cpu(sb->new_layout); | 1723 | mddev->new_layout = le32_to_cpu(sb->new_layout); |
1664 | mddev->new_chunk_sectors = le32_to_cpu(sb->new_chunk); | 1724 | mddev->new_chunk_sectors = le32_to_cpu(sb->new_chunk); |
1725 | if (mddev->delta_disks < 0 || | ||
1726 | (mddev->delta_disks == 0 && | ||
1727 | (le32_to_cpu(sb->feature_map) | ||
1728 | & MD_FEATURE_RESHAPE_BACKWARDS))) | ||
1729 | mddev->reshape_backwards = 1; | ||
1665 | } else { | 1730 | } else { |
1666 | mddev->reshape_position = MaxSector; | 1731 | mddev->reshape_position = MaxSector; |
1667 | mddev->delta_disks = 0; | 1732 | mddev->delta_disks = 0; |
@@ -1735,7 +1800,6 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev) | |||
1735 | sb->feature_map = 0; | 1800 | sb->feature_map = 0; |
1736 | sb->pad0 = 0; | 1801 | sb->pad0 = 0; |
1737 | sb->recovery_offset = cpu_to_le64(0); | 1802 | sb->recovery_offset = cpu_to_le64(0); |
1738 | memset(sb->pad1, 0, sizeof(sb->pad1)); | ||
1739 | memset(sb->pad3, 0, sizeof(sb->pad3)); | 1803 | memset(sb->pad3, 0, sizeof(sb->pad3)); |
1740 | 1804 | ||
1741 | sb->utime = cpu_to_le64((__u64)mddev->utime); | 1805 | sb->utime = cpu_to_le64((__u64)mddev->utime); |
@@ -1757,6 +1821,8 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev) | |||
1757 | sb->devflags |= WriteMostly1; | 1821 | sb->devflags |= WriteMostly1; |
1758 | else | 1822 | else |
1759 | sb->devflags &= ~WriteMostly1; | 1823 | sb->devflags &= ~WriteMostly1; |
1824 | sb->data_offset = cpu_to_le64(rdev->data_offset); | ||
1825 | sb->data_size = cpu_to_le64(rdev->sectors); | ||
1760 | 1826 | ||
1761 | if (mddev->bitmap && mddev->bitmap_info.file == NULL) { | 1827 | if (mddev->bitmap && mddev->bitmap_info.file == NULL) { |
1762 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); | 1828 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); |
@@ -1781,6 +1847,16 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev) | |||
1781 | sb->delta_disks = cpu_to_le32(mddev->delta_disks); | 1847 | sb->delta_disks = cpu_to_le32(mddev->delta_disks); |
1782 | sb->new_level = cpu_to_le32(mddev->new_level); | 1848 | sb->new_level = cpu_to_le32(mddev->new_level); |
1783 | sb->new_chunk = cpu_to_le32(mddev->new_chunk_sectors); | 1849 | sb->new_chunk = cpu_to_le32(mddev->new_chunk_sectors); |
1850 | if (mddev->delta_disks == 0 && | ||
1851 | mddev->reshape_backwards) | ||
1852 | sb->feature_map | ||
1853 | |= cpu_to_le32(MD_FEATURE_RESHAPE_BACKWARDS); | ||
1854 | if (rdev->new_data_offset != rdev->data_offset) { | ||
1855 | sb->feature_map | ||
1856 | |= cpu_to_le32(MD_FEATURE_NEW_OFFSET); | ||
1857 | sb->new_offset = cpu_to_le32((__u32)(rdev->new_data_offset | ||
1858 | - rdev->data_offset)); | ||
1859 | } | ||
1784 | } | 1860 | } |
1785 | 1861 | ||
1786 | if (rdev->badblocks.count == 0) | 1862 | if (rdev->badblocks.count == 0) |
@@ -1857,6 +1933,8 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
1857 | sector_t max_sectors; | 1933 | sector_t max_sectors; |
1858 | if (num_sectors && num_sectors < rdev->mddev->dev_sectors) | 1934 | if (num_sectors && num_sectors < rdev->mddev->dev_sectors) |
1859 | return 0; /* component must fit device */ | 1935 | return 0; /* component must fit device */ |
1936 | if (rdev->data_offset != rdev->new_data_offset) | ||
1937 | return 0; /* too confusing */ | ||
1860 | if (rdev->sb_start < rdev->data_offset) { | 1938 | if (rdev->sb_start < rdev->data_offset) { |
1861 | /* minor versions 1 and 2; superblock before data */ | 1939 | /* minor versions 1 and 2; superblock before data */ |
1862 | max_sectors = i_size_read(rdev->bdev->bd_inode) >> 9; | 1940 | max_sectors = i_size_read(rdev->bdev->bd_inode) >> 9; |
@@ -1884,6 +1962,40 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
1884 | rdev->sb_page); | 1962 | rdev->sb_page); |
1885 | md_super_wait(rdev->mddev); | 1963 | md_super_wait(rdev->mddev); |
1886 | return num_sectors; | 1964 | return num_sectors; |
1965 | |||
1966 | } | ||
1967 | |||
1968 | static int | ||
1969 | super_1_allow_new_offset(struct md_rdev *rdev, | ||
1970 | unsigned long long new_offset) | ||
1971 | { | ||
1972 | /* All necessary checks on new >= old have been done */ | ||
1973 | struct bitmap *bitmap; | ||
1974 | if (new_offset >= rdev->data_offset) | ||
1975 | return 1; | ||
1976 | |||
1977 | /* with 1.0 metadata, there is no metadata to tread on | ||
1978 | * so we can always move back */ | ||
1979 | if (rdev->mddev->minor_version == 0) | ||
1980 | return 1; | ||
1981 | |||
1982 | /* otherwise we must be sure not to step on | ||
1983 | * any metadata, so stay: | ||
1984 | * 36K beyond start of superblock | ||
1985 | * beyond end of badblocks | ||
1986 | * beyond write-intent bitmap | ||
1987 | */ | ||
1988 | if (rdev->sb_start + (32+4)*2 > new_offset) | ||
1989 | return 0; | ||
1990 | bitmap = rdev->mddev->bitmap; | ||
1991 | if (bitmap && !rdev->mddev->bitmap_info.file && | ||
1992 | rdev->sb_start + rdev->mddev->bitmap_info.offset + | ||
1993 | bitmap->storage.file_pages * (PAGE_SIZE>>9) > new_offset) | ||
1994 | return 0; | ||
1995 | if (rdev->badblocks.sector + rdev->badblocks.size > new_offset) | ||
1996 | return 0; | ||
1997 | |||
1998 | return 1; | ||
1887 | } | 1999 | } |
1888 | 2000 | ||
1889 | static struct super_type super_types[] = { | 2001 | static struct super_type super_types[] = { |
@@ -1894,6 +2006,7 @@ static struct super_type super_types[] = { | |||
1894 | .validate_super = super_90_validate, | 2006 | .validate_super = super_90_validate, |
1895 | .sync_super = super_90_sync, | 2007 | .sync_super = super_90_sync, |
1896 | .rdev_size_change = super_90_rdev_size_change, | 2008 | .rdev_size_change = super_90_rdev_size_change, |
2009 | .allow_new_offset = super_90_allow_new_offset, | ||
1897 | }, | 2010 | }, |
1898 | [1] = { | 2011 | [1] = { |
1899 | .name = "md-1", | 2012 | .name = "md-1", |
@@ -1902,6 +2015,7 @@ static struct super_type super_types[] = { | |||
1902 | .validate_super = super_1_validate, | 2015 | .validate_super = super_1_validate, |
1903 | .sync_super = super_1_sync, | 2016 | .sync_super = super_1_sync, |
1904 | .rdev_size_change = super_1_rdev_size_change, | 2017 | .rdev_size_change = super_1_rdev_size_change, |
2018 | .allow_new_offset = super_1_allow_new_offset, | ||
1905 | }, | 2019 | }, |
1906 | }; | 2020 | }; |
1907 | 2021 | ||
@@ -2105,9 +2219,7 @@ static void unbind_rdev_from_array(struct md_rdev * rdev) | |||
2105 | sysfs_remove_link(&rdev->kobj, "block"); | 2219 | sysfs_remove_link(&rdev->kobj, "block"); |
2106 | sysfs_put(rdev->sysfs_state); | 2220 | sysfs_put(rdev->sysfs_state); |
2107 | rdev->sysfs_state = NULL; | 2221 | rdev->sysfs_state = NULL; |
2108 | kfree(rdev->badblocks.page); | ||
2109 | rdev->badblocks.count = 0; | 2222 | rdev->badblocks.count = 0; |
2110 | rdev->badblocks.page = NULL; | ||
2111 | /* We need to delay this, otherwise we can deadlock when | 2223 | /* We need to delay this, otherwise we can deadlock when |
2112 | * writing to 'remove' to "dev/state". We also need | 2224 | * writing to 'remove' to "dev/state". We also need |
2113 | * to delay it due to rcu usage. | 2225 | * to delay it due to rcu usage. |
@@ -2158,7 +2270,7 @@ static void export_rdev(struct md_rdev * rdev) | |||
2158 | bdevname(rdev->bdev,b)); | 2270 | bdevname(rdev->bdev,b)); |
2159 | if (rdev->mddev) | 2271 | if (rdev->mddev) |
2160 | MD_BUG(); | 2272 | MD_BUG(); |
2161 | free_disk_sb(rdev); | 2273 | md_rdev_clear(rdev); |
2162 | #ifndef MODULE | 2274 | #ifndef MODULE |
2163 | if (test_bit(AutoDetected, &rdev->flags)) | 2275 | if (test_bit(AutoDetected, &rdev->flags)) |
2164 | md_autodetect_dev(rdev->bdev->bd_dev); | 2276 | md_autodetect_dev(rdev->bdev->bd_dev); |
@@ -2809,9 +2921,8 @@ offset_show(struct md_rdev *rdev, char *page) | |||
2809 | static ssize_t | 2921 | static ssize_t |
2810 | offset_store(struct md_rdev *rdev, const char *buf, size_t len) | 2922 | offset_store(struct md_rdev *rdev, const char *buf, size_t len) |
2811 | { | 2923 | { |
2812 | char *e; | 2924 | unsigned long long offset; |
2813 | unsigned long long offset = simple_strtoull(buf, &e, 10); | 2925 | if (strict_strtoull(buf, 10, &offset) < 0) |
2814 | if (e==buf || (*e && *e != '\n')) | ||
2815 | return -EINVAL; | 2926 | return -EINVAL; |
2816 | if (rdev->mddev->pers && rdev->raid_disk >= 0) | 2927 | if (rdev->mddev->pers && rdev->raid_disk >= 0) |
2817 | return -EBUSY; | 2928 | return -EBUSY; |
@@ -2826,6 +2937,63 @@ offset_store(struct md_rdev *rdev, const char *buf, size_t len) | |||
2826 | static struct rdev_sysfs_entry rdev_offset = | 2937 | static struct rdev_sysfs_entry rdev_offset = |
2827 | __ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store); | 2938 | __ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store); |
2828 | 2939 | ||
2940 | static ssize_t new_offset_show(struct md_rdev *rdev, char *page) | ||
2941 | { | ||
2942 | return sprintf(page, "%llu\n", | ||
2943 | (unsigned long long)rdev->new_data_offset); | ||
2944 | } | ||
2945 | |||
2946 | static ssize_t new_offset_store(struct md_rdev *rdev, | ||
2947 | const char *buf, size_t len) | ||
2948 | { | ||
2949 | unsigned long long new_offset; | ||
2950 | struct mddev *mddev = rdev->mddev; | ||
2951 | |||
2952 | if (strict_strtoull(buf, 10, &new_offset) < 0) | ||
2953 | return -EINVAL; | ||
2954 | |||
2955 | if (mddev->sync_thread) | ||
2956 | return -EBUSY; | ||
2957 | if (new_offset == rdev->data_offset) | ||
2958 | /* reset is always permitted */ | ||
2959 | ; | ||
2960 | else if (new_offset > rdev->data_offset) { | ||
2961 | /* must not push array size beyond rdev_sectors */ | ||
2962 | if (new_offset - rdev->data_offset | ||
2963 | + mddev->dev_sectors > rdev->sectors) | ||
2964 | return -E2BIG; | ||
2965 | } | ||
2966 | /* Metadata worries about other space details. */ | ||
2967 | |||
2968 | /* decreasing the offset is inconsistent with a backwards | ||
2969 | * reshape. | ||
2970 | */ | ||
2971 | if (new_offset < rdev->data_offset && | ||
2972 | mddev->reshape_backwards) | ||
2973 | return -EINVAL; | ||
2974 | /* Increasing offset is inconsistent with forwards | ||
2975 | * reshape. reshape_direction should be set to | ||
2976 | * 'backwards' first. | ||
2977 | */ | ||
2978 | if (new_offset > rdev->data_offset && | ||
2979 | !mddev->reshape_backwards) | ||
2980 | return -EINVAL; | ||
2981 | |||
2982 | if (mddev->pers && mddev->persistent && | ||
2983 | !super_types[mddev->major_version] | ||
2984 | .allow_new_offset(rdev, new_offset)) | ||
2985 | return -E2BIG; | ||
2986 | rdev->new_data_offset = new_offset; | ||
2987 | if (new_offset > rdev->data_offset) | ||
2988 | mddev->reshape_backwards = 1; | ||
2989 | else if (new_offset < rdev->data_offset) | ||
2990 | mddev->reshape_backwards = 0; | ||
2991 | |||
2992 | return len; | ||
2993 | } | ||
2994 | static struct rdev_sysfs_entry rdev_new_offset = | ||
2995 | __ATTR(new_offset, S_IRUGO|S_IWUSR, new_offset_show, new_offset_store); | ||
2996 | |||
2829 | static ssize_t | 2997 | static ssize_t |
2830 | rdev_size_show(struct md_rdev *rdev, char *page) | 2998 | rdev_size_show(struct md_rdev *rdev, char *page) |
2831 | { | 2999 | { |
@@ -2870,6 +3038,8 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len) | |||
2870 | 3038 | ||
2871 | if (strict_blocks_to_sectors(buf, §ors) < 0) | 3039 | if (strict_blocks_to_sectors(buf, §ors) < 0) |
2872 | return -EINVAL; | 3040 | return -EINVAL; |
3041 | if (rdev->data_offset != rdev->new_data_offset) | ||
3042 | return -EINVAL; /* too confusing */ | ||
2873 | if (my_mddev->pers && rdev->raid_disk >= 0) { | 3043 | if (my_mddev->pers && rdev->raid_disk >= 0) { |
2874 | if (my_mddev->persistent) { | 3044 | if (my_mddev->persistent) { |
2875 | sectors = super_types[my_mddev->major_version]. | 3045 | sectors = super_types[my_mddev->major_version]. |
@@ -3006,6 +3176,7 @@ static struct attribute *rdev_default_attrs[] = { | |||
3006 | &rdev_errors.attr, | 3176 | &rdev_errors.attr, |
3007 | &rdev_slot.attr, | 3177 | &rdev_slot.attr, |
3008 | &rdev_offset.attr, | 3178 | &rdev_offset.attr, |
3179 | &rdev_new_offset.attr, | ||
3009 | &rdev_size.attr, | 3180 | &rdev_size.attr, |
3010 | &rdev_recovery_start.attr, | 3181 | &rdev_recovery_start.attr, |
3011 | &rdev_bad_blocks.attr, | 3182 | &rdev_bad_blocks.attr, |
@@ -3080,6 +3251,7 @@ int md_rdev_init(struct md_rdev *rdev) | |||
3080 | rdev->raid_disk = -1; | 3251 | rdev->raid_disk = -1; |
3081 | rdev->flags = 0; | 3252 | rdev->flags = 0; |
3082 | rdev->data_offset = 0; | 3253 | rdev->data_offset = 0; |
3254 | rdev->new_data_offset = 0; | ||
3083 | rdev->sb_events = 0; | 3255 | rdev->sb_events = 0; |
3084 | rdev->last_read_error.tv_sec = 0; | 3256 | rdev->last_read_error.tv_sec = 0; |
3085 | rdev->last_read_error.tv_nsec = 0; | 3257 | rdev->last_read_error.tv_nsec = 0; |
@@ -3178,8 +3350,7 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe | |||
3178 | abort_free: | 3350 | abort_free: |
3179 | if (rdev->bdev) | 3351 | if (rdev->bdev) |
3180 | unlock_rdev(rdev); | 3352 | unlock_rdev(rdev); |
3181 | free_disk_sb(rdev); | 3353 | md_rdev_clear(rdev); |
3182 | kfree(rdev->badblocks.page); | ||
3183 | kfree(rdev); | 3354 | kfree(rdev); |
3184 | return ERR_PTR(err); | 3355 | return ERR_PTR(err); |
3185 | } | 3356 | } |
@@ -3419,6 +3590,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len) | |||
3419 | mddev->new_chunk_sectors = mddev->chunk_sectors; | 3590 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
3420 | mddev->raid_disks -= mddev->delta_disks; | 3591 | mddev->raid_disks -= mddev->delta_disks; |
3421 | mddev->delta_disks = 0; | 3592 | mddev->delta_disks = 0; |
3593 | mddev->reshape_backwards = 0; | ||
3422 | module_put(pers->owner); | 3594 | module_put(pers->owner); |
3423 | printk(KERN_WARNING "md: %s: %s would not accept array\n", | 3595 | printk(KERN_WARNING "md: %s: %s would not accept array\n", |
3424 | mdname(mddev), clevel); | 3596 | mdname(mddev), clevel); |
@@ -3492,6 +3664,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len) | |||
3492 | mddev->layout = mddev->new_layout; | 3664 | mddev->layout = mddev->new_layout; |
3493 | mddev->chunk_sectors = mddev->new_chunk_sectors; | 3665 | mddev->chunk_sectors = mddev->new_chunk_sectors; |
3494 | mddev->delta_disks = 0; | 3666 | mddev->delta_disks = 0; |
3667 | mddev->reshape_backwards = 0; | ||
3495 | mddev->degraded = 0; | 3668 | mddev->degraded = 0; |
3496 | if (mddev->pers->sync_request == NULL) { | 3669 | if (mddev->pers->sync_request == NULL) { |
3497 | /* this is now an array without redundancy, so | 3670 | /* this is now an array without redundancy, so |
@@ -3501,10 +3674,8 @@ level_store(struct mddev *mddev, const char *buf, size_t len) | |||
3501 | del_timer_sync(&mddev->safemode_timer); | 3674 | del_timer_sync(&mddev->safemode_timer); |
3502 | } | 3675 | } |
3503 | pers->run(mddev); | 3676 | pers->run(mddev); |
3504 | mddev_resume(mddev); | ||
3505 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 3677 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
3506 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3678 | mddev_resume(mddev); |
3507 | md_wakeup_thread(mddev->thread); | ||
3508 | sysfs_notify(&mddev->kobj, NULL, "level"); | 3679 | sysfs_notify(&mddev->kobj, NULL, "level"); |
3509 | md_new_event(mddev); | 3680 | md_new_event(mddev); |
3510 | return rv; | 3681 | return rv; |
@@ -3582,9 +3753,20 @@ raid_disks_store(struct mddev *mddev, const char *buf, size_t len) | |||
3582 | if (mddev->pers) | 3753 | if (mddev->pers) |
3583 | rv = update_raid_disks(mddev, n); | 3754 | rv = update_raid_disks(mddev, n); |
3584 | else if (mddev->reshape_position != MaxSector) { | 3755 | else if (mddev->reshape_position != MaxSector) { |
3756 | struct md_rdev *rdev; | ||
3585 | int olddisks = mddev->raid_disks - mddev->delta_disks; | 3757 | int olddisks = mddev->raid_disks - mddev->delta_disks; |
3758 | |||
3759 | rdev_for_each(rdev, mddev) { | ||
3760 | if (olddisks < n && | ||
3761 | rdev->data_offset < rdev->new_data_offset) | ||
3762 | return -EINVAL; | ||
3763 | if (olddisks > n && | ||
3764 | rdev->data_offset > rdev->new_data_offset) | ||
3765 | return -EINVAL; | ||
3766 | } | ||
3586 | mddev->delta_disks = n - olddisks; | 3767 | mddev->delta_disks = n - olddisks; |
3587 | mddev->raid_disks = n; | 3768 | mddev->raid_disks = n; |
3769 | mddev->reshape_backwards = (mddev->delta_disks < 0); | ||
3588 | } else | 3770 | } else |
3589 | mddev->raid_disks = n; | 3771 | mddev->raid_disks = n; |
3590 | return rv ? rv : len; | 3772 | return rv ? rv : len; |
@@ -4266,7 +4448,8 @@ sync_completed_show(struct mddev *mddev, char *page) | |||
4266 | if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 4448 | if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
4267 | return sprintf(page, "none\n"); | 4449 | return sprintf(page, "none\n"); |
4268 | 4450 | ||
4269 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 4451 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) || |
4452 | test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | ||
4270 | max_sectors = mddev->resync_max_sectors; | 4453 | max_sectors = mddev->resync_max_sectors; |
4271 | else | 4454 | else |
4272 | max_sectors = mddev->dev_sectors; | 4455 | max_sectors = mddev->dev_sectors; |
@@ -4428,6 +4611,7 @@ reshape_position_show(struct mddev *mddev, char *page) | |||
4428 | static ssize_t | 4611 | static ssize_t |
4429 | reshape_position_store(struct mddev *mddev, const char *buf, size_t len) | 4612 | reshape_position_store(struct mddev *mddev, const char *buf, size_t len) |
4430 | { | 4613 | { |
4614 | struct md_rdev *rdev; | ||
4431 | char *e; | 4615 | char *e; |
4432 | unsigned long long new = simple_strtoull(buf, &e, 10); | 4616 | unsigned long long new = simple_strtoull(buf, &e, 10); |
4433 | if (mddev->pers) | 4617 | if (mddev->pers) |
@@ -4436,9 +4620,12 @@ reshape_position_store(struct mddev *mddev, const char *buf, size_t len) | |||
4436 | return -EINVAL; | 4620 | return -EINVAL; |
4437 | mddev->reshape_position = new; | 4621 | mddev->reshape_position = new; |
4438 | mddev->delta_disks = 0; | 4622 | mddev->delta_disks = 0; |
4623 | mddev->reshape_backwards = 0; | ||
4439 | mddev->new_level = mddev->level; | 4624 | mddev->new_level = mddev->level; |
4440 | mddev->new_layout = mddev->layout; | 4625 | mddev->new_layout = mddev->layout; |
4441 | mddev->new_chunk_sectors = mddev->chunk_sectors; | 4626 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
4627 | rdev_for_each(rdev, mddev) | ||
4628 | rdev->new_data_offset = rdev->data_offset; | ||
4442 | return len; | 4629 | return len; |
4443 | } | 4630 | } |
4444 | 4631 | ||
@@ -4447,6 +4634,42 @@ __ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show, | |||
4447 | reshape_position_store); | 4634 | reshape_position_store); |
4448 | 4635 | ||
4449 | static ssize_t | 4636 | static ssize_t |
4637 | reshape_direction_show(struct mddev *mddev, char *page) | ||
4638 | { | ||
4639 | return sprintf(page, "%s\n", | ||
4640 | mddev->reshape_backwards ? "backwards" : "forwards"); | ||
4641 | } | ||
4642 | |||
4643 | static ssize_t | ||
4644 | reshape_direction_store(struct mddev *mddev, const char *buf, size_t len) | ||
4645 | { | ||
4646 | int backwards = 0; | ||
4647 | if (cmd_match(buf, "forwards")) | ||
4648 | backwards = 0; | ||
4649 | else if (cmd_match(buf, "backwards")) | ||
4650 | backwards = 1; | ||
4651 | else | ||
4652 | return -EINVAL; | ||
4653 | if (mddev->reshape_backwards == backwards) | ||
4654 | return len; | ||
4655 | |||
4656 | /* check if we are allowed to change */ | ||
4657 | if (mddev->delta_disks) | ||
4658 | return -EBUSY; | ||
4659 | |||
4660 | if (mddev->persistent && | ||
4661 | mddev->major_version == 0) | ||
4662 | return -EINVAL; | ||
4663 | |||
4664 | mddev->reshape_backwards = backwards; | ||
4665 | return len; | ||
4666 | } | ||
4667 | |||
4668 | static struct md_sysfs_entry md_reshape_direction = | ||
4669 | __ATTR(reshape_direction, S_IRUGO|S_IWUSR, reshape_direction_show, | ||
4670 | reshape_direction_store); | ||
4671 | |||
4672 | static ssize_t | ||
4450 | array_size_show(struct mddev *mddev, char *page) | 4673 | array_size_show(struct mddev *mddev, char *page) |
4451 | { | 4674 | { |
4452 | if (mddev->external_size) | 4675 | if (mddev->external_size) |
@@ -4501,6 +4724,7 @@ static struct attribute *md_default_attrs[] = { | |||
4501 | &md_safe_delay.attr, | 4724 | &md_safe_delay.attr, |
4502 | &md_array_state.attr, | 4725 | &md_array_state.attr, |
4503 | &md_reshape_position.attr, | 4726 | &md_reshape_position.attr, |
4727 | &md_reshape_direction.attr, | ||
4504 | &md_array_size.attr, | 4728 | &md_array_size.attr, |
4505 | &max_corr_read_errors.attr, | 4729 | &max_corr_read_errors.attr, |
4506 | NULL, | 4730 | NULL, |
@@ -4914,7 +5138,8 @@ int md_run(struct mddev *mddev) | |||
4914 | err = -EINVAL; | 5138 | err = -EINVAL; |
4915 | mddev->pers->stop(mddev); | 5139 | mddev->pers->stop(mddev); |
4916 | } | 5140 | } |
4917 | if (err == 0 && mddev->pers->sync_request) { | 5141 | if (err == 0 && mddev->pers->sync_request && |
5142 | (mddev->bitmap_info.file || mddev->bitmap_info.offset)) { | ||
4918 | err = bitmap_create(mddev); | 5143 | err = bitmap_create(mddev); |
4919 | if (err) { | 5144 | if (err) { |
4920 | printk(KERN_ERR "%s: failed to create bitmap (%d)\n", | 5145 | printk(KERN_ERR "%s: failed to create bitmap (%d)\n", |
@@ -5064,6 +5289,7 @@ static void md_clean(struct mddev *mddev) | |||
5064 | mddev->events = 0; | 5289 | mddev->events = 0; |
5065 | mddev->can_decrease_events = 0; | 5290 | mddev->can_decrease_events = 0; |
5066 | mddev->delta_disks = 0; | 5291 | mddev->delta_disks = 0; |
5292 | mddev->reshape_backwards = 0; | ||
5067 | mddev->new_level = LEVEL_NONE; | 5293 | mddev->new_level = LEVEL_NONE; |
5068 | mddev->new_layout = 0; | 5294 | mddev->new_layout = 0; |
5069 | mddev->new_chunk_sectors = 0; | 5295 | mddev->new_chunk_sectors = 0; |
@@ -5079,6 +5305,7 @@ static void md_clean(struct mddev *mddev) | |||
5079 | mddev->merge_check_needed = 0; | 5305 | mddev->merge_check_needed = 0; |
5080 | mddev->bitmap_info.offset = 0; | 5306 | mddev->bitmap_info.offset = 0; |
5081 | mddev->bitmap_info.default_offset = 0; | 5307 | mddev->bitmap_info.default_offset = 0; |
5308 | mddev->bitmap_info.default_space = 0; | ||
5082 | mddev->bitmap_info.chunksize = 0; | 5309 | mddev->bitmap_info.chunksize = 0; |
5083 | mddev->bitmap_info.daemon_sleep = 0; | 5310 | mddev->bitmap_info.daemon_sleep = 0; |
5084 | mddev->bitmap_info.max_write_behind = 0; | 5311 | mddev->bitmap_info.max_write_behind = 0; |
@@ -5421,7 +5648,7 @@ static int get_bitmap_file(struct mddev * mddev, void __user * arg) | |||
5421 | goto out; | 5648 | goto out; |
5422 | 5649 | ||
5423 | /* bitmap disabled, zero the first byte and copy out */ | 5650 | /* bitmap disabled, zero the first byte and copy out */ |
5424 | if (!mddev->bitmap || !mddev->bitmap->file) { | 5651 | if (!mddev->bitmap || !mddev->bitmap->storage.file) { |
5425 | file->pathname[0] = '\0'; | 5652 | file->pathname[0] = '\0'; |
5426 | goto copy_out; | 5653 | goto copy_out; |
5427 | } | 5654 | } |
@@ -5430,7 +5657,8 @@ static int get_bitmap_file(struct mddev * mddev, void __user * arg) | |||
5430 | if (!buf) | 5657 | if (!buf) |
5431 | goto out; | 5658 | goto out; |
5432 | 5659 | ||
5433 | ptr = d_path(&mddev->bitmap->file->f_path, buf, sizeof(file->pathname)); | 5660 | ptr = d_path(&mddev->bitmap->storage.file->f_path, |
5661 | buf, sizeof(file->pathname)); | ||
5434 | if (IS_ERR(ptr)) | 5662 | if (IS_ERR(ptr)) |
5435 | goto out; | 5663 | goto out; |
5436 | 5664 | ||
@@ -5875,6 +6103,7 @@ static int set_array_info(struct mddev * mddev, mdu_array_info_t *info) | |||
5875 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 6103 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
5876 | 6104 | ||
5877 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; | 6105 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; |
6106 | mddev->bitmap_info.default_space = 64*2 - (MD_SB_BYTES >> 9); | ||
5878 | mddev->bitmap_info.offset = 0; | 6107 | mddev->bitmap_info.offset = 0; |
5879 | 6108 | ||
5880 | mddev->reshape_position = MaxSector; | 6109 | mddev->reshape_position = MaxSector; |
@@ -5888,6 +6117,7 @@ static int set_array_info(struct mddev * mddev, mdu_array_info_t *info) | |||
5888 | mddev->new_chunk_sectors = mddev->chunk_sectors; | 6117 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
5889 | mddev->new_layout = mddev->layout; | 6118 | mddev->new_layout = mddev->layout; |
5890 | mddev->delta_disks = 0; | 6119 | mddev->delta_disks = 0; |
6120 | mddev->reshape_backwards = 0; | ||
5891 | 6121 | ||
5892 | return 0; | 6122 | return 0; |
5893 | } | 6123 | } |
@@ -5922,11 +6152,7 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) | |||
5922 | */ | 6152 | */ |
5923 | if (mddev->sync_thread) | 6153 | if (mddev->sync_thread) |
5924 | return -EBUSY; | 6154 | return -EBUSY; |
5925 | if (mddev->bitmap) | 6155 | |
5926 | /* Sorry, cannot grow a bitmap yet, just remove it, | ||
5927 | * grow, and re-add. | ||
5928 | */ | ||
5929 | return -EBUSY; | ||
5930 | rdev_for_each(rdev, mddev) { | 6156 | rdev_for_each(rdev, mddev) { |
5931 | sector_t avail = rdev->sectors; | 6157 | sector_t avail = rdev->sectors; |
5932 | 6158 | ||
@@ -5944,6 +6170,7 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) | |||
5944 | static int update_raid_disks(struct mddev *mddev, int raid_disks) | 6170 | static int update_raid_disks(struct mddev *mddev, int raid_disks) |
5945 | { | 6171 | { |
5946 | int rv; | 6172 | int rv; |
6173 | struct md_rdev *rdev; | ||
5947 | /* change the number of raid disks */ | 6174 | /* change the number of raid disks */ |
5948 | if (mddev->pers->check_reshape == NULL) | 6175 | if (mddev->pers->check_reshape == NULL) |
5949 | return -EINVAL; | 6176 | return -EINVAL; |
@@ -5952,11 +6179,27 @@ static int update_raid_disks(struct mddev *mddev, int raid_disks) | |||
5952 | return -EINVAL; | 6179 | return -EINVAL; |
5953 | if (mddev->sync_thread || mddev->reshape_position != MaxSector) | 6180 | if (mddev->sync_thread || mddev->reshape_position != MaxSector) |
5954 | return -EBUSY; | 6181 | return -EBUSY; |
6182 | |||
6183 | rdev_for_each(rdev, mddev) { | ||
6184 | if (mddev->raid_disks < raid_disks && | ||
6185 | rdev->data_offset < rdev->new_data_offset) | ||
6186 | return -EINVAL; | ||
6187 | if (mddev->raid_disks > raid_disks && | ||
6188 | rdev->data_offset > rdev->new_data_offset) | ||
6189 | return -EINVAL; | ||
6190 | } | ||
6191 | |||
5955 | mddev->delta_disks = raid_disks - mddev->raid_disks; | 6192 | mddev->delta_disks = raid_disks - mddev->raid_disks; |
6193 | if (mddev->delta_disks < 0) | ||
6194 | mddev->reshape_backwards = 1; | ||
6195 | else if (mddev->delta_disks > 0) | ||
6196 | mddev->reshape_backwards = 0; | ||
5956 | 6197 | ||
5957 | rv = mddev->pers->check_reshape(mddev); | 6198 | rv = mddev->pers->check_reshape(mddev); |
5958 | if (rv < 0) | 6199 | if (rv < 0) { |
5959 | mddev->delta_disks = 0; | 6200 | mddev->delta_disks = 0; |
6201 | mddev->reshape_backwards = 0; | ||
6202 | } | ||
5960 | return rv; | 6203 | return rv; |
5961 | } | 6204 | } |
5962 | 6205 | ||
@@ -6039,6 +6282,8 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) | |||
6039 | return -EINVAL; | 6282 | return -EINVAL; |
6040 | mddev->bitmap_info.offset = | 6283 | mddev->bitmap_info.offset = |
6041 | mddev->bitmap_info.default_offset; | 6284 | mddev->bitmap_info.default_offset; |
6285 | mddev->bitmap_info.space = | ||
6286 | mddev->bitmap_info.default_space; | ||
6042 | mddev->pers->quiesce(mddev, 1); | 6287 | mddev->pers->quiesce(mddev, 1); |
6043 | rv = bitmap_create(mddev); | 6288 | rv = bitmap_create(mddev); |
6044 | if (!rv) | 6289 | if (!rv) |
@@ -6050,7 +6295,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info) | |||
6050 | /* remove the bitmap */ | 6295 | /* remove the bitmap */ |
6051 | if (!mddev->bitmap) | 6296 | if (!mddev->bitmap) |
6052 | return -ENOENT; | 6297 | return -ENOENT; |
6053 | if (mddev->bitmap->file) | 6298 | if (mddev->bitmap->storage.file) |
6054 | return -EINVAL; | 6299 | return -EINVAL; |
6055 | mddev->pers->quiesce(mddev, 1); | 6300 | mddev->pers->quiesce(mddev, 1); |
6056 | bitmap_destroy(mddev); | 6301 | bitmap_destroy(mddev); |
@@ -6373,6 +6618,9 @@ static int md_open(struct block_device *bdev, fmode_t mode) | |||
6373 | struct mddev *mddev = mddev_find(bdev->bd_dev); | 6618 | struct mddev *mddev = mddev_find(bdev->bd_dev); |
6374 | int err; | 6619 | int err; |
6375 | 6620 | ||
6621 | if (!mddev) | ||
6622 | return -ENODEV; | ||
6623 | |||
6376 | if (mddev->gendisk != bdev->bd_disk) { | 6624 | if (mddev->gendisk != bdev->bd_disk) { |
6377 | /* we are racing with mddev_put which is discarding this | 6625 | /* we are racing with mddev_put which is discarding this |
6378 | * bd_disk. | 6626 | * bd_disk. |
@@ -6584,7 +6832,8 @@ static void status_resync(struct seq_file *seq, struct mddev * mddev) | |||
6584 | 6832 | ||
6585 | resync = mddev->curr_resync - atomic_read(&mddev->recovery_active); | 6833 | resync = mddev->curr_resync - atomic_read(&mddev->recovery_active); |
6586 | 6834 | ||
6587 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 6835 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) || |
6836 | test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | ||
6588 | max_sectors = mddev->resync_max_sectors; | 6837 | max_sectors = mddev->resync_max_sectors; |
6589 | else | 6838 | else |
6590 | max_sectors = mddev->dev_sectors; | 6839 | max_sectors = mddev->dev_sectors; |
@@ -7147,7 +7396,7 @@ void md_do_sync(struct mddev *mddev) | |||
7147 | j = mddev->recovery_cp; | 7396 | j = mddev->recovery_cp; |
7148 | 7397 | ||
7149 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | 7398 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) |
7150 | max_sectors = mddev->dev_sectors; | 7399 | max_sectors = mddev->resync_max_sectors; |
7151 | else { | 7400 | else { |
7152 | /* recovery follows the physical size of devices */ | 7401 | /* recovery follows the physical size of devices */ |
7153 | max_sectors = mddev->dev_sectors; | 7402 | max_sectors = mddev->dev_sectors; |
@@ -7598,7 +7847,7 @@ void md_check_recovery(struct mddev *mddev) | |||
7598 | goto unlock; | 7847 | goto unlock; |
7599 | 7848 | ||
7600 | if (mddev->pers->sync_request) { | 7849 | if (mddev->pers->sync_request) { |
7601 | if (spares && mddev->bitmap && ! mddev->bitmap->file) { | 7850 | if (spares) { |
7602 | /* We are adding a device or devices to an array | 7851 | /* We are adding a device or devices to an array |
7603 | * which has the bitmap stored on all devices. | 7852 | * which has the bitmap stored on all devices. |
7604 | * So make sure all bitmap pages get written | 7853 | * So make sure all bitmap pages get written |
@@ -7646,6 +7895,20 @@ void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev) | |||
7646 | } | 7895 | } |
7647 | EXPORT_SYMBOL(md_wait_for_blocked_rdev); | 7896 | EXPORT_SYMBOL(md_wait_for_blocked_rdev); |
7648 | 7897 | ||
7898 | void md_finish_reshape(struct mddev *mddev) | ||
7899 | { | ||
7900 | /* called be personality module when reshape completes. */ | ||
7901 | struct md_rdev *rdev; | ||
7902 | |||
7903 | rdev_for_each(rdev, mddev) { | ||
7904 | if (rdev->data_offset > rdev->new_data_offset) | ||
7905 | rdev->sectors += rdev->data_offset - rdev->new_data_offset; | ||
7906 | else | ||
7907 | rdev->sectors -= rdev->new_data_offset - rdev->data_offset; | ||
7908 | rdev->data_offset = rdev->new_data_offset; | ||
7909 | } | ||
7910 | } | ||
7911 | EXPORT_SYMBOL(md_finish_reshape); | ||
7649 | 7912 | ||
7650 | /* Bad block management. | 7913 | /* Bad block management. |
7651 | * We can record which blocks on each device are 'bad' and so just | 7914 | * We can record which blocks on each device are 'bad' and so just |
@@ -7894,10 +8157,15 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors, | |||
7894 | } | 8157 | } |
7895 | 8158 | ||
7896 | int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, | 8159 | int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, |
7897 | int acknowledged) | 8160 | int is_new) |
7898 | { | 8161 | { |
7899 | int rv = md_set_badblocks(&rdev->badblocks, | 8162 | int rv; |
7900 | s + rdev->data_offset, sectors, acknowledged); | 8163 | if (is_new) |
8164 | s += rdev->new_data_offset; | ||
8165 | else | ||
8166 | s += rdev->data_offset; | ||
8167 | rv = md_set_badblocks(&rdev->badblocks, | ||
8168 | s, sectors, 0); | ||
7901 | if (rv) { | 8169 | if (rv) { |
7902 | /* Make sure they get written out promptly */ | 8170 | /* Make sure they get written out promptly */ |
7903 | sysfs_notify_dirent_safe(rdev->sysfs_state); | 8171 | sysfs_notify_dirent_safe(rdev->sysfs_state); |
@@ -8003,11 +8271,15 @@ out: | |||
8003 | return rv; | 8271 | return rv; |
8004 | } | 8272 | } |
8005 | 8273 | ||
8006 | int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors) | 8274 | int rdev_clear_badblocks(struct md_rdev *rdev, sector_t s, int sectors, |
8275 | int is_new) | ||
8007 | { | 8276 | { |
8277 | if (is_new) | ||
8278 | s += rdev->new_data_offset; | ||
8279 | else | ||
8280 | s += rdev->data_offset; | ||
8008 | return md_clear_badblocks(&rdev->badblocks, | 8281 | return md_clear_badblocks(&rdev->badblocks, |
8009 | s + rdev->data_offset, | 8282 | s, sectors); |
8010 | sectors); | ||
8011 | } | 8283 | } |
8012 | EXPORT_SYMBOL_GPL(rdev_clear_badblocks); | 8284 | EXPORT_SYMBOL_GPL(rdev_clear_badblocks); |
8013 | 8285 | ||