diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 198 |
1 files changed, 77 insertions, 121 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 641b211fe3fe..09be637d52cb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -440,15 +440,6 @@ static inline sector_t calc_dev_sboffset(struct block_device *bdev) | |||
440 | return MD_NEW_SIZE_SECTORS(num_sectors); | 440 | return MD_NEW_SIZE_SECTORS(num_sectors); |
441 | } | 441 | } |
442 | 442 | ||
443 | static sector_t calc_num_sectors(mdk_rdev_t *rdev, unsigned chunk_size) | ||
444 | { | ||
445 | sector_t num_sectors = rdev->sb_start; | ||
446 | |||
447 | if (chunk_size) | ||
448 | num_sectors &= ~((sector_t)chunk_size/512 - 1); | ||
449 | return num_sectors; | ||
450 | } | ||
451 | |||
452 | static int alloc_disk_sb(mdk_rdev_t * rdev) | 443 | static int alloc_disk_sb(mdk_rdev_t * rdev) |
453 | { | 444 | { |
454 | if (rdev->sb_page) | 445 | if (rdev->sb_page) |
@@ -745,6 +736,24 @@ struct super_type { | |||
745 | }; | 736 | }; |
746 | 737 | ||
747 | /* | 738 | /* |
739 | * Check that the given mddev has no bitmap. | ||
740 | * | ||
741 | * This function is called from the run method of all personalities that do not | ||
742 | * support bitmaps. It prints an error message and returns non-zero if mddev | ||
743 | * has a bitmap. Otherwise, it returns 0. | ||
744 | * | ||
745 | */ | ||
746 | int md_check_no_bitmap(mddev_t *mddev) | ||
747 | { | ||
748 | if (!mddev->bitmap_file && !mddev->bitmap_offset) | ||
749 | return 0; | ||
750 | printk(KERN_ERR "%s: bitmaps are not supported for %s\n", | ||
751 | mdname(mddev), mddev->pers->name); | ||
752 | return 1; | ||
753 | } | ||
754 | EXPORT_SYMBOL(md_check_no_bitmap); | ||
755 | |||
756 | /* | ||
748 | * load_super for 0.90.0 | 757 | * load_super for 0.90.0 |
749 | */ | 758 | */ |
750 | static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | 759 | static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) |
@@ -797,17 +806,6 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version | |||
797 | rdev->data_offset = 0; | 806 | rdev->data_offset = 0; |
798 | rdev->sb_size = MD_SB_BYTES; | 807 | rdev->sb_size = MD_SB_BYTES; |
799 | 808 | ||
800 | if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) { | ||
801 | if (sb->level != 1 && sb->level != 4 | ||
802 | && sb->level != 5 && sb->level != 6 | ||
803 | && sb->level != 10) { | ||
804 | /* FIXME use a better test */ | ||
805 | printk(KERN_WARNING | ||
806 | "md: bitmaps not supported for this level.\n"); | ||
807 | goto abort; | ||
808 | } | ||
809 | } | ||
810 | |||
811 | if (sb->level == LEVEL_MULTIPATH) | 809 | if (sb->level == LEVEL_MULTIPATH) |
812 | rdev->desc_nr = -1; | 810 | rdev->desc_nr = -1; |
813 | else | 811 | else |
@@ -836,7 +834,7 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version | |||
836 | else | 834 | else |
837 | ret = 0; | 835 | ret = 0; |
838 | } | 836 | } |
839 | rdev->sectors = calc_num_sectors(rdev, sb->chunk_size); | 837 | rdev->sectors = rdev->sb_start; |
840 | 838 | ||
841 | if (rdev->sectors < sb->size * 2 && sb->level > 1) | 839 | if (rdev->sectors < sb->size * 2 && sb->level > 1) |
842 | /* "this cannot possibly happen" ... */ | 840 | /* "this cannot possibly happen" ... */ |
@@ -866,7 +864,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
866 | mddev->minor_version = sb->minor_version; | 864 | mddev->minor_version = sb->minor_version; |
867 | mddev->patch_version = sb->patch_version; | 865 | mddev->patch_version = sb->patch_version; |
868 | mddev->external = 0; | 866 | mddev->external = 0; |
869 | mddev->chunk_size = sb->chunk_size; | 867 | mddev->chunk_sectors = sb->chunk_size >> 9; |
870 | mddev->ctime = sb->ctime; | 868 | mddev->ctime = sb->ctime; |
871 | mddev->utime = sb->utime; | 869 | mddev->utime = sb->utime; |
872 | mddev->level = sb->level; | 870 | mddev->level = sb->level; |
@@ -883,13 +881,13 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
883 | mddev->delta_disks = sb->delta_disks; | 881 | mddev->delta_disks = sb->delta_disks; |
884 | mddev->new_level = sb->new_level; | 882 | mddev->new_level = sb->new_level; |
885 | mddev->new_layout = sb->new_layout; | 883 | mddev->new_layout = sb->new_layout; |
886 | mddev->new_chunk = sb->new_chunk; | 884 | mddev->new_chunk_sectors = sb->new_chunk >> 9; |
887 | } else { | 885 | } else { |
888 | mddev->reshape_position = MaxSector; | 886 | mddev->reshape_position = MaxSector; |
889 | mddev->delta_disks = 0; | 887 | mddev->delta_disks = 0; |
890 | mddev->new_level = mddev->level; | 888 | mddev->new_level = mddev->level; |
891 | mddev->new_layout = mddev->layout; | 889 | mddev->new_layout = mddev->layout; |
892 | mddev->new_chunk = mddev->chunk_size; | 890 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
893 | } | 891 | } |
894 | 892 | ||
895 | if (sb->state & (1<<MD_SB_CLEAN)) | 893 | if (sb->state & (1<<MD_SB_CLEAN)) |
@@ -1004,7 +1002,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1004 | sb->new_level = mddev->new_level; | 1002 | sb->new_level = mddev->new_level; |
1005 | sb->delta_disks = mddev->delta_disks; | 1003 | sb->delta_disks = mddev->delta_disks; |
1006 | sb->new_layout = mddev->new_layout; | 1004 | sb->new_layout = mddev->new_layout; |
1007 | sb->new_chunk = mddev->new_chunk; | 1005 | sb->new_chunk = mddev->new_chunk_sectors << 9; |
1008 | } | 1006 | } |
1009 | mddev->minor_version = sb->minor_version; | 1007 | mddev->minor_version = sb->minor_version; |
1010 | if (mddev->in_sync) | 1008 | if (mddev->in_sync) |
@@ -1018,7 +1016,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1018 | sb->recovery_cp = 0; | 1016 | sb->recovery_cp = 0; |
1019 | 1017 | ||
1020 | sb->layout = mddev->layout; | 1018 | sb->layout = mddev->layout; |
1021 | sb->chunk_size = mddev->chunk_size; | 1019 | sb->chunk_size = mddev->chunk_sectors << 9; |
1022 | 1020 | ||
1023 | if (mddev->bitmap && mddev->bitmap_file == NULL) | 1021 | if (mddev->bitmap && mddev->bitmap_file == NULL) |
1024 | sb->state |= (1<<MD_SB_BITMAP_PRESENT); | 1022 | sb->state |= (1<<MD_SB_BITMAP_PRESENT); |
@@ -1185,24 +1183,13 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1185 | bdevname(rdev->bdev,b)); | 1183 | bdevname(rdev->bdev,b)); |
1186 | return -EINVAL; | 1184 | return -EINVAL; |
1187 | } | 1185 | } |
1188 | if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) { | ||
1189 | if (sb->level != cpu_to_le32(1) && | ||
1190 | sb->level != cpu_to_le32(4) && | ||
1191 | sb->level != cpu_to_le32(5) && | ||
1192 | sb->level != cpu_to_le32(6) && | ||
1193 | sb->level != cpu_to_le32(10)) { | ||
1194 | printk(KERN_WARNING | ||
1195 | "md: bitmaps not supported for this level.\n"); | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1198 | } | ||
1199 | 1186 | ||
1200 | rdev->preferred_minor = 0xffff; | 1187 | rdev->preferred_minor = 0xffff; |
1201 | rdev->data_offset = le64_to_cpu(sb->data_offset); | 1188 | rdev->data_offset = le64_to_cpu(sb->data_offset); |
1202 | atomic_set(&rdev->corrected_errors, le32_to_cpu(sb->cnt_corrected_read)); | 1189 | atomic_set(&rdev->corrected_errors, le32_to_cpu(sb->cnt_corrected_read)); |
1203 | 1190 | ||
1204 | rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; | 1191 | rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; |
1205 | bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1; | 1192 | bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1; |
1206 | if (rdev->sb_size & bmask) | 1193 | if (rdev->sb_size & bmask) |
1207 | rdev->sb_size = (rdev->sb_size | bmask) + 1; | 1194 | rdev->sb_size = (rdev->sb_size | bmask) + 1; |
1208 | 1195 | ||
@@ -1248,9 +1235,6 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
1248 | if (rdev->sectors < le64_to_cpu(sb->data_size)) | 1235 | if (rdev->sectors < le64_to_cpu(sb->data_size)) |
1249 | return -EINVAL; | 1236 | return -EINVAL; |
1250 | rdev->sectors = le64_to_cpu(sb->data_size); | 1237 | rdev->sectors = le64_to_cpu(sb->data_size); |
1251 | if (le32_to_cpu(sb->chunksize)) | ||
1252 | rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1); | ||
1253 | |||
1254 | if (le64_to_cpu(sb->size) > rdev->sectors) | 1238 | if (le64_to_cpu(sb->size) > rdev->sectors) |
1255 | return -EINVAL; | 1239 | return -EINVAL; |
1256 | return ret; | 1240 | return ret; |
@@ -1271,7 +1255,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1271 | mddev->major_version = 1; | 1255 | mddev->major_version = 1; |
1272 | mddev->patch_version = 0; | 1256 | mddev->patch_version = 0; |
1273 | mddev->external = 0; | 1257 | mddev->external = 0; |
1274 | mddev->chunk_size = le32_to_cpu(sb->chunksize) << 9; | 1258 | mddev->chunk_sectors = le32_to_cpu(sb->chunksize); |
1275 | mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1); | 1259 | mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1); |
1276 | mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1); | 1260 | mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1); |
1277 | mddev->level = le32_to_cpu(sb->level); | 1261 | mddev->level = le32_to_cpu(sb->level); |
@@ -1297,13 +1281,13 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1297 | mddev->delta_disks = le32_to_cpu(sb->delta_disks); | 1281 | mddev->delta_disks = le32_to_cpu(sb->delta_disks); |
1298 | mddev->new_level = le32_to_cpu(sb->new_level); | 1282 | mddev->new_level = le32_to_cpu(sb->new_level); |
1299 | mddev->new_layout = le32_to_cpu(sb->new_layout); | 1283 | mddev->new_layout = le32_to_cpu(sb->new_layout); |
1300 | mddev->new_chunk = le32_to_cpu(sb->new_chunk)<<9; | 1284 | mddev->new_chunk_sectors = le32_to_cpu(sb->new_chunk); |
1301 | } else { | 1285 | } else { |
1302 | mddev->reshape_position = MaxSector; | 1286 | mddev->reshape_position = MaxSector; |
1303 | mddev->delta_disks = 0; | 1287 | mddev->delta_disks = 0; |
1304 | mddev->new_level = mddev->level; | 1288 | mddev->new_level = mddev->level; |
1305 | mddev->new_layout = mddev->layout; | 1289 | mddev->new_layout = mddev->layout; |
1306 | mddev->new_chunk = mddev->chunk_size; | 1290 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
1307 | } | 1291 | } |
1308 | 1292 | ||
1309 | } else if (mddev->pers == NULL) { | 1293 | } else if (mddev->pers == NULL) { |
@@ -1375,7 +1359,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1375 | 1359 | ||
1376 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); | 1360 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); |
1377 | sb->size = cpu_to_le64(mddev->dev_sectors); | 1361 | sb->size = cpu_to_le64(mddev->dev_sectors); |
1378 | sb->chunksize = cpu_to_le32(mddev->chunk_size >> 9); | 1362 | sb->chunksize = cpu_to_le32(mddev->chunk_sectors); |
1379 | sb->level = cpu_to_le32(mddev->level); | 1363 | sb->level = cpu_to_le32(mddev->level); |
1380 | sb->layout = cpu_to_le32(mddev->layout); | 1364 | sb->layout = cpu_to_le32(mddev->layout); |
1381 | 1365 | ||
@@ -1402,7 +1386,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1402 | sb->new_layout = cpu_to_le32(mddev->new_layout); | 1386 | sb->new_layout = cpu_to_le32(mddev->new_layout); |
1403 | sb->delta_disks = cpu_to_le32(mddev->delta_disks); | 1387 | sb->delta_disks = cpu_to_le32(mddev->delta_disks); |
1404 | sb->new_level = cpu_to_le32(mddev->new_level); | 1388 | sb->new_level = cpu_to_le32(mddev->new_level); |
1405 | sb->new_chunk = cpu_to_le32(mddev->new_chunk>>9); | 1389 | sb->new_chunk = cpu_to_le32(mddev->new_chunk_sectors); |
1406 | } | 1390 | } |
1407 | 1391 | ||
1408 | max_dev = 0; | 1392 | max_dev = 0; |
@@ -1897,6 +1881,7 @@ static void md_update_sb(mddev_t * mddev, int force_change) | |||
1897 | int sync_req; | 1881 | int sync_req; |
1898 | int nospares = 0; | 1882 | int nospares = 0; |
1899 | 1883 | ||
1884 | mddev->utime = get_seconds(); | ||
1900 | if (mddev->external) | 1885 | if (mddev->external) |
1901 | return; | 1886 | return; |
1902 | repeat: | 1887 | repeat: |
@@ -1926,7 +1911,6 @@ repeat: | |||
1926 | nospares = 0; | 1911 | nospares = 0; |
1927 | 1912 | ||
1928 | sync_req = mddev->in_sync; | 1913 | sync_req = mddev->in_sync; |
1929 | mddev->utime = get_seconds(); | ||
1930 | 1914 | ||
1931 | /* If this is just a dirty<->clean transition, and the array is clean | 1915 | /* If this is just a dirty<->clean transition, and the array is clean |
1932 | * and 'events' is odd, we can roll back to the previous clean state */ | 1916 | * and 'events' is odd, we can roll back to the previous clean state */ |
@@ -2597,15 +2581,6 @@ static void analyze_sbs(mddev_t * mddev) | |||
2597 | clear_bit(In_sync, &rdev->flags); | 2581 | clear_bit(In_sync, &rdev->flags); |
2598 | } | 2582 | } |
2599 | } | 2583 | } |
2600 | |||
2601 | |||
2602 | |||
2603 | if (mddev->recovery_cp != MaxSector && | ||
2604 | mddev->level >= 1) | ||
2605 | printk(KERN_ERR "md: %s: raid array is not clean" | ||
2606 | " -- starting background reconstruction\n", | ||
2607 | mdname(mddev)); | ||
2608 | |||
2609 | } | 2584 | } |
2610 | 2585 | ||
2611 | static void md_safemode_timeout(unsigned long data); | 2586 | static void md_safemode_timeout(unsigned long data); |
@@ -2746,7 +2721,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) | |||
2746 | if (IS_ERR(priv)) { | 2721 | if (IS_ERR(priv)) { |
2747 | mddev->new_level = mddev->level; | 2722 | mddev->new_level = mddev->level; |
2748 | mddev->new_layout = mddev->layout; | 2723 | mddev->new_layout = mddev->layout; |
2749 | mddev->new_chunk = mddev->chunk_size; | 2724 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
2750 | mddev->raid_disks -= mddev->delta_disks; | 2725 | mddev->raid_disks -= mddev->delta_disks; |
2751 | mddev->delta_disks = 0; | 2726 | mddev->delta_disks = 0; |
2752 | module_put(pers->owner); | 2727 | module_put(pers->owner); |
@@ -2764,7 +2739,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) | |||
2764 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); | 2739 | strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); |
2765 | mddev->level = mddev->new_level; | 2740 | mddev->level = mddev->new_level; |
2766 | mddev->layout = mddev->new_layout; | 2741 | mddev->layout = mddev->new_layout; |
2767 | mddev->chunk_size = mddev->new_chunk; | 2742 | mddev->chunk_sectors = mddev->new_chunk_sectors; |
2768 | mddev->delta_disks = 0; | 2743 | mddev->delta_disks = 0; |
2769 | pers->run(mddev); | 2744 | pers->run(mddev); |
2770 | mddev_resume(mddev); | 2745 | mddev_resume(mddev); |
@@ -2800,11 +2775,14 @@ layout_store(mddev_t *mddev, const char *buf, size_t len) | |||
2800 | 2775 | ||
2801 | if (mddev->pers) { | 2776 | if (mddev->pers) { |
2802 | int err; | 2777 | int err; |
2803 | if (mddev->pers->reconfig == NULL) | 2778 | if (mddev->pers->check_reshape == NULL) |
2804 | return -EBUSY; | 2779 | return -EBUSY; |
2805 | err = mddev->pers->reconfig(mddev, n, -1); | 2780 | mddev->new_layout = n; |
2806 | if (err) | 2781 | err = mddev->pers->check_reshape(mddev); |
2782 | if (err) { | ||
2783 | mddev->new_layout = mddev->layout; | ||
2807 | return err; | 2784 | return err; |
2785 | } | ||
2808 | } else { | 2786 | } else { |
2809 | mddev->new_layout = n; | 2787 | mddev->new_layout = n; |
2810 | if (mddev->reshape_position == MaxSector) | 2788 | if (mddev->reshape_position == MaxSector) |
@@ -2857,10 +2835,11 @@ static ssize_t | |||
2857 | chunk_size_show(mddev_t *mddev, char *page) | 2835 | chunk_size_show(mddev_t *mddev, char *page) |
2858 | { | 2836 | { |
2859 | if (mddev->reshape_position != MaxSector && | 2837 | if (mddev->reshape_position != MaxSector && |
2860 | mddev->chunk_size != mddev->new_chunk) | 2838 | mddev->chunk_sectors != mddev->new_chunk_sectors) |
2861 | return sprintf(page, "%d (%d)\n", mddev->new_chunk, | 2839 | return sprintf(page, "%d (%d)\n", |
2862 | mddev->chunk_size); | 2840 | mddev->new_chunk_sectors << 9, |
2863 | return sprintf(page, "%d\n", mddev->chunk_size); | 2841 | mddev->chunk_sectors << 9); |
2842 | return sprintf(page, "%d\n", mddev->chunk_sectors << 9); | ||
2864 | } | 2843 | } |
2865 | 2844 | ||
2866 | static ssize_t | 2845 | static ssize_t |
@@ -2874,15 +2853,18 @@ chunk_size_store(mddev_t *mddev, const char *buf, size_t len) | |||
2874 | 2853 | ||
2875 | if (mddev->pers) { | 2854 | if (mddev->pers) { |
2876 | int err; | 2855 | int err; |
2877 | if (mddev->pers->reconfig == NULL) | 2856 | if (mddev->pers->check_reshape == NULL) |
2878 | return -EBUSY; | 2857 | return -EBUSY; |
2879 | err = mddev->pers->reconfig(mddev, -1, n); | 2858 | mddev->new_chunk_sectors = n >> 9; |
2880 | if (err) | 2859 | err = mddev->pers->check_reshape(mddev); |
2860 | if (err) { | ||
2861 | mddev->new_chunk_sectors = mddev->chunk_sectors; | ||
2881 | return err; | 2862 | return err; |
2863 | } | ||
2882 | } else { | 2864 | } else { |
2883 | mddev->new_chunk = n; | 2865 | mddev->new_chunk_sectors = n >> 9; |
2884 | if (mddev->reshape_position == MaxSector) | 2866 | if (mddev->reshape_position == MaxSector) |
2885 | mddev->chunk_size = n; | 2867 | mddev->chunk_sectors = n >> 9; |
2886 | } | 2868 | } |
2887 | return len; | 2869 | return len; |
2888 | } | 2870 | } |
@@ -3527,8 +3509,9 @@ min_sync_store(mddev_t *mddev, const char *buf, size_t len) | |||
3527 | return -EBUSY; | 3509 | return -EBUSY; |
3528 | 3510 | ||
3529 | /* Must be a multiple of chunk_size */ | 3511 | /* Must be a multiple of chunk_size */ |
3530 | if (mddev->chunk_size) { | 3512 | if (mddev->chunk_sectors) { |
3531 | if (min & (sector_t)((mddev->chunk_size>>9)-1)) | 3513 | sector_t temp = min; |
3514 | if (sector_div(temp, mddev->chunk_sectors)) | ||
3532 | return -EINVAL; | 3515 | return -EINVAL; |
3533 | } | 3516 | } |
3534 | mddev->resync_min = min; | 3517 | mddev->resync_min = min; |
@@ -3564,8 +3547,9 @@ max_sync_store(mddev_t *mddev, const char *buf, size_t len) | |||
3564 | return -EBUSY; | 3547 | return -EBUSY; |
3565 | 3548 | ||
3566 | /* Must be a multiple of chunk_size */ | 3549 | /* Must be a multiple of chunk_size */ |
3567 | if (mddev->chunk_size) { | 3550 | if (mddev->chunk_sectors) { |
3568 | if (max & (sector_t)((mddev->chunk_size>>9)-1)) | 3551 | sector_t temp = max; |
3552 | if (sector_div(temp, mddev->chunk_sectors)) | ||
3569 | return -EINVAL; | 3553 | return -EINVAL; |
3570 | } | 3554 | } |
3571 | mddev->resync_max = max; | 3555 | mddev->resync_max = max; |
@@ -3656,7 +3640,7 @@ reshape_position_store(mddev_t *mddev, const char *buf, size_t len) | |||
3656 | mddev->delta_disks = 0; | 3640 | mddev->delta_disks = 0; |
3657 | mddev->new_level = mddev->level; | 3641 | mddev->new_level = mddev->level; |
3658 | mddev->new_layout = mddev->layout; | 3642 | mddev->new_layout = mddev->layout; |
3659 | mddev->new_chunk = mddev->chunk_size; | 3643 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
3660 | return len; | 3644 | return len; |
3661 | } | 3645 | } |
3662 | 3646 | ||
@@ -3976,11 +3960,9 @@ static int start_dirty_degraded; | |||
3976 | static int do_md_run(mddev_t * mddev) | 3960 | static int do_md_run(mddev_t * mddev) |
3977 | { | 3961 | { |
3978 | int err; | 3962 | int err; |
3979 | int chunk_size; | ||
3980 | mdk_rdev_t *rdev; | 3963 | mdk_rdev_t *rdev; |
3981 | struct gendisk *disk; | 3964 | struct gendisk *disk; |
3982 | struct mdk_personality *pers; | 3965 | struct mdk_personality *pers; |
3983 | char b[BDEVNAME_SIZE]; | ||
3984 | 3966 | ||
3985 | if (list_empty(&mddev->disks)) | 3967 | if (list_empty(&mddev->disks)) |
3986 | /* cannot run an array with no devices.. */ | 3968 | /* cannot run an array with no devices.. */ |
@@ -3998,38 +3980,6 @@ static int do_md_run(mddev_t * mddev) | |||
3998 | analyze_sbs(mddev); | 3980 | analyze_sbs(mddev); |
3999 | } | 3981 | } |
4000 | 3982 | ||
4001 | chunk_size = mddev->chunk_size; | ||
4002 | |||
4003 | if (chunk_size) { | ||
4004 | if (chunk_size > MAX_CHUNK_SIZE) { | ||
4005 | printk(KERN_ERR "too big chunk_size: %d > %d\n", | ||
4006 | chunk_size, MAX_CHUNK_SIZE); | ||
4007 | return -EINVAL; | ||
4008 | } | ||
4009 | /* | ||
4010 | * chunk-size has to be a power of 2 | ||
4011 | */ | ||
4012 | if ( (1 << ffz(~chunk_size)) != chunk_size) { | ||
4013 | printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size); | ||
4014 | return -EINVAL; | ||
4015 | } | ||
4016 | |||
4017 | /* devices must have minimum size of one chunk */ | ||
4018 | list_for_each_entry(rdev, &mddev->disks, same_set) { | ||
4019 | if (test_bit(Faulty, &rdev->flags)) | ||
4020 | continue; | ||
4021 | if (rdev->sectors < chunk_size / 512) { | ||
4022 | printk(KERN_WARNING | ||
4023 | "md: Dev %s smaller than chunk_size:" | ||
4024 | " %llu < %d\n", | ||
4025 | bdevname(rdev->bdev,b), | ||
4026 | (unsigned long long)rdev->sectors, | ||
4027 | chunk_size / 512); | ||
4028 | return -EINVAL; | ||
4029 | } | ||
4030 | } | ||
4031 | } | ||
4032 | |||
4033 | if (mddev->level != LEVEL_NONE) | 3983 | if (mddev->level != LEVEL_NONE) |
4034 | request_module("md-level-%d", mddev->level); | 3984 | request_module("md-level-%d", mddev->level); |
4035 | else if (mddev->clevel[0]) | 3985 | else if (mddev->clevel[0]) |
@@ -4405,7 +4355,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
4405 | mddev->flags = 0; | 4355 | mddev->flags = 0; |
4406 | mddev->ro = 0; | 4356 | mddev->ro = 0; |
4407 | mddev->metadata_type[0] = 0; | 4357 | mddev->metadata_type[0] = 0; |
4408 | mddev->chunk_size = 0; | 4358 | mddev->chunk_sectors = 0; |
4409 | mddev->ctime = mddev->utime = 0; | 4359 | mddev->ctime = mddev->utime = 0; |
4410 | mddev->layout = 0; | 4360 | mddev->layout = 0; |
4411 | mddev->max_disks = 0; | 4361 | mddev->max_disks = 0; |
@@ -4413,7 +4363,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
4413 | mddev->delta_disks = 0; | 4363 | mddev->delta_disks = 0; |
4414 | mddev->new_level = LEVEL_NONE; | 4364 | mddev->new_level = LEVEL_NONE; |
4415 | mddev->new_layout = 0; | 4365 | mddev->new_layout = 0; |
4416 | mddev->new_chunk = 0; | 4366 | mddev->new_chunk_sectors = 0; |
4417 | mddev->curr_resync = 0; | 4367 | mddev->curr_resync = 0; |
4418 | mddev->resync_mismatches = 0; | 4368 | mddev->resync_mismatches = 0; |
4419 | mddev->suspend_lo = mddev->suspend_hi = 0; | 4369 | mddev->suspend_lo = mddev->suspend_hi = 0; |
@@ -4618,7 +4568,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
4618 | info.spare_disks = spare; | 4568 | info.spare_disks = spare; |
4619 | 4569 | ||
4620 | info.layout = mddev->layout; | 4570 | info.layout = mddev->layout; |
4621 | info.chunk_size = mddev->chunk_size; | 4571 | info.chunk_size = mddev->chunk_sectors << 9; |
4622 | 4572 | ||
4623 | if (copy_to_user(arg, &info, sizeof(info))) | 4573 | if (copy_to_user(arg, &info, sizeof(info))) |
4624 | return -EFAULT; | 4574 | return -EFAULT; |
@@ -4843,7 +4793,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
4843 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; | 4793 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; |
4844 | } else | 4794 | } else |
4845 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); | 4795 | rdev->sb_start = calc_dev_sboffset(rdev->bdev); |
4846 | rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size); | 4796 | rdev->sectors = rdev->sb_start; |
4847 | 4797 | ||
4848 | err = bind_rdev_to_array(rdev, mddev); | 4798 | err = bind_rdev_to_array(rdev, mddev); |
4849 | if (err) { | 4799 | if (err) { |
@@ -4913,7 +4863,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
4913 | else | 4863 | else |
4914 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; | 4864 | rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; |
4915 | 4865 | ||
4916 | rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size); | 4866 | rdev->sectors = rdev->sb_start; |
4917 | 4867 | ||
4918 | if (test_bit(Faulty, &rdev->flags)) { | 4868 | if (test_bit(Faulty, &rdev->flags)) { |
4919 | printk(KERN_WARNING | 4869 | printk(KERN_WARNING |
@@ -5062,7 +5012,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
5062 | mddev->external = 0; | 5012 | mddev->external = 0; |
5063 | 5013 | ||
5064 | mddev->layout = info->layout; | 5014 | mddev->layout = info->layout; |
5065 | mddev->chunk_size = info->chunk_size; | 5015 | mddev->chunk_sectors = info->chunk_size >> 9; |
5066 | 5016 | ||
5067 | mddev->max_disks = MD_SB_DISKS; | 5017 | mddev->max_disks = MD_SB_DISKS; |
5068 | 5018 | ||
@@ -5081,7 +5031,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
5081 | get_random_bytes(mddev->uuid, 16); | 5031 | get_random_bytes(mddev->uuid, 16); |
5082 | 5032 | ||
5083 | mddev->new_level = mddev->level; | 5033 | mddev->new_level = mddev->level; |
5084 | mddev->new_chunk = mddev->chunk_size; | 5034 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
5085 | mddev->new_layout = mddev->layout; | 5035 | mddev->new_layout = mddev->layout; |
5086 | mddev->delta_disks = 0; | 5036 | mddev->delta_disks = 0; |
5087 | 5037 | ||
@@ -5191,7 +5141,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
5191 | mddev->level != info->level || | 5141 | mddev->level != info->level || |
5192 | /* mddev->layout != info->layout || */ | 5142 | /* mddev->layout != info->layout || */ |
5193 | !mddev->persistent != info->not_persistent|| | 5143 | !mddev->persistent != info->not_persistent|| |
5194 | mddev->chunk_size != info->chunk_size || | 5144 | mddev->chunk_sectors != info->chunk_size >> 9 || |
5195 | /* ignore bottom 8 bits of state, and allow SB_BITMAP_PRESENT to change */ | 5145 | /* ignore bottom 8 bits of state, and allow SB_BITMAP_PRESENT to change */ |
5196 | ((state^info->state) & 0xfffffe00) | 5146 | ((state^info->state) & 0xfffffe00) |
5197 | ) | 5147 | ) |
@@ -5215,10 +5165,15 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
5215 | * we don't need to do anything at the md level, the | 5165 | * we don't need to do anything at the md level, the |
5216 | * personality will take care of it all. | 5166 | * personality will take care of it all. |
5217 | */ | 5167 | */ |
5218 | if (mddev->pers->reconfig == NULL) | 5168 | if (mddev->pers->check_reshape == NULL) |
5219 | return -EINVAL; | 5169 | return -EINVAL; |
5220 | else | 5170 | else { |
5221 | return mddev->pers->reconfig(mddev, info->layout, -1); | 5171 | mddev->new_layout = info->layout; |
5172 | rv = mddev->pers->check_reshape(mddev); | ||
5173 | if (rv) | ||
5174 | mddev->new_layout = mddev->layout; | ||
5175 | return rv; | ||
5176 | } | ||
5222 | } | 5177 | } |
5223 | if (info->size >= 0 && mddev->dev_sectors / 2 != info->size) | 5178 | if (info->size >= 0 && mddev->dev_sectors / 2 != info->size) |
5224 | rv = update_size(mddev, (sector_t)info->size * 2); | 5179 | rv = update_size(mddev, (sector_t)info->size * 2); |
@@ -6717,7 +6672,8 @@ void md_check_recovery(mddev_t *mddev) | |||
6717 | */ | 6672 | */ |
6718 | 6673 | ||
6719 | if (mddev->reshape_position != MaxSector) { | 6674 | if (mddev->reshape_position != MaxSector) { |
6720 | if (mddev->pers->check_reshape(mddev) != 0) | 6675 | if (mddev->pers->check_reshape == NULL || |
6676 | mddev->pers->check_reshape(mddev) != 0) | ||
6721 | /* Cannot proceed */ | 6677 | /* Cannot proceed */ |
6722 | goto unlock; | 6678 | goto unlock; |
6723 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); | 6679 | set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); |