diff options
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index b2c00ce602b1..be4a131e8c01 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -816,7 +816,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
816 | mddev->clevel[0] = 0; | 816 | mddev->clevel[0] = 0; |
817 | mddev->layout = sb->layout; | 817 | mddev->layout = sb->layout; |
818 | mddev->raid_disks = sb->raid_disks; | 818 | mddev->raid_disks = sb->raid_disks; |
819 | mddev->size = sb->size; | 819 | mddev->dev_sectors = sb->size * 2; |
820 | mddev->events = ev1; | 820 | mddev->events = ev1; |
821 | mddev->bitmap_offset = 0; | 821 | mddev->bitmap_offset = 0; |
822 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; | 822 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; |
@@ -930,7 +930,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
930 | 930 | ||
931 | sb->ctime = mddev->ctime; | 931 | sb->ctime = mddev->ctime; |
932 | sb->level = mddev->level; | 932 | sb->level = mddev->level; |
933 | sb->size = mddev->size; | 933 | sb->size = mddev->dev_sectors / 2; |
934 | sb->raid_disks = mddev->raid_disks; | 934 | sb->raid_disks = mddev->raid_disks; |
935 | sb->md_minor = mddev->md_minor; | 935 | sb->md_minor = mddev->md_minor; |
936 | sb->not_persistent = 0; | 936 | sb->not_persistent = 0; |
@@ -1028,7 +1028,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1028 | static unsigned long long | 1028 | static unsigned long long |
1029 | super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | 1029 | super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) |
1030 | { | 1030 | { |
1031 | if (num_sectors && num_sectors < rdev->mddev->size * 2) | 1031 | if (num_sectors && num_sectors < rdev->mddev->dev_sectors) |
1032 | return 0; /* component must fit device */ | 1032 | return 0; /* component must fit device */ |
1033 | if (rdev->mddev->bitmap_offset) | 1033 | if (rdev->mddev->bitmap_offset) |
1034 | return 0; /* can't move bitmap */ | 1034 | return 0; /* can't move bitmap */ |
@@ -1220,7 +1220,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1220 | mddev->clevel[0] = 0; | 1220 | mddev->clevel[0] = 0; |
1221 | mddev->layout = le32_to_cpu(sb->layout); | 1221 | mddev->layout = le32_to_cpu(sb->layout); |
1222 | mddev->raid_disks = le32_to_cpu(sb->raid_disks); | 1222 | mddev->raid_disks = le32_to_cpu(sb->raid_disks); |
1223 | mddev->size = le64_to_cpu(sb->size)/2; | 1223 | mddev->dev_sectors = le64_to_cpu(sb->size); |
1224 | mddev->events = ev1; | 1224 | mddev->events = ev1; |
1225 | mddev->bitmap_offset = 0; | 1225 | mddev->bitmap_offset = 0; |
1226 | mddev->default_bitmap_offset = 1024 >> 9; | 1226 | mddev->default_bitmap_offset = 1024 >> 9; |
@@ -1316,7 +1316,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1316 | sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors)); | 1316 | sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors)); |
1317 | 1317 | ||
1318 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); | 1318 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); |
1319 | sb->size = cpu_to_le64(mddev->size<<1); | 1319 | sb->size = cpu_to_le64(mddev->dev_sectors); |
1320 | 1320 | ||
1321 | if (mddev->bitmap && mddev->bitmap_file == NULL) { | 1321 | if (mddev->bitmap && mddev->bitmap_file == NULL) { |
1322 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); | 1322 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); |
@@ -1374,7 +1374,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | |||
1374 | { | 1374 | { |
1375 | struct mdp_superblock_1 *sb; | 1375 | struct mdp_superblock_1 *sb; |
1376 | sector_t max_sectors; | 1376 | sector_t max_sectors; |
1377 | if (num_sectors && num_sectors < rdev->mddev->size * 2) | 1377 | if (num_sectors && num_sectors < rdev->mddev->dev_sectors) |
1378 | return 0; /* component must fit device */ | 1378 | return 0; /* component must fit device */ |
1379 | if (rdev->sb_start < rdev->data_offset) { | 1379 | if (rdev->sb_start < rdev->data_offset) { |
1380 | /* minor versions 1 and 2; superblock before data */ | 1380 | /* minor versions 1 and 2; superblock before data */ |
@@ -1490,8 +1490,9 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1490 | if (find_rdev(mddev, rdev->bdev->bd_dev)) | 1490 | if (find_rdev(mddev, rdev->bdev->bd_dev)) |
1491 | return -EEXIST; | 1491 | return -EEXIST; |
1492 | 1492 | ||
1493 | /* make sure rdev->size exceeds mddev->size */ | 1493 | /* make sure rdev->size exceeds mddev->dev_sectors / 2 */ |
1494 | if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) { | 1494 | if (rdev->size && (mddev->dev_sectors == 0 || |
1495 | rdev->size < mddev->dev_sectors / 2)) { | ||
1495 | if (mddev->pers) { | 1496 | if (mddev->pers) { |
1496 | /* Cannot change size, so fail | 1497 | /* Cannot change size, so fail |
1497 | * If mddev->level <= 0, then we don't care | 1498 | * If mddev->level <= 0, then we don't care |
@@ -1500,7 +1501,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1500 | if (mddev->level > 0) | 1501 | if (mddev->level > 0) |
1501 | return -ENOSPC; | 1502 | return -ENOSPC; |
1502 | } else | 1503 | } else |
1503 | mddev->size = rdev->size; | 1504 | mddev->dev_sectors = rdev->size * 2; |
1504 | } | 1505 | } |
1505 | 1506 | ||
1506 | /* Verify rdev->desc_nr is unique. | 1507 | /* Verify rdev->desc_nr is unique. |
@@ -2243,7 +2244,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2243 | size -= rdev->data_offset/2; | 2244 | size -= rdev->data_offset/2; |
2244 | } | 2245 | } |
2245 | } | 2246 | } |
2246 | if (size < my_mddev->size) | 2247 | if (size < my_mddev->dev_sectors / 2) |
2247 | return -EINVAL; /* component must fit device */ | 2248 | return -EINVAL; /* component must fit device */ |
2248 | 2249 | ||
2249 | rdev->size = size; | 2250 | rdev->size = size; |
@@ -2809,7 +2810,7 @@ array_state_show(mddev_t *mddev, char *page) | |||
2809 | else { | 2810 | else { |
2810 | if (list_empty(&mddev->disks) && | 2811 | if (list_empty(&mddev->disks) && |
2811 | mddev->raid_disks == 0 && | 2812 | mddev->raid_disks == 0 && |
2812 | mddev->size == 0) | 2813 | mddev->dev_sectors == 0) |
2813 | st = clear; | 2814 | st = clear; |
2814 | else | 2815 | else |
2815 | st = inactive; | 2816 | st = inactive; |
@@ -3016,7 +3017,8 @@ __ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store); | |||
3016 | static ssize_t | 3017 | static ssize_t |
3017 | size_show(mddev_t *mddev, char *page) | 3018 | size_show(mddev_t *mddev, char *page) |
3018 | { | 3019 | { |
3019 | return sprintf(page, "%llu\n", (unsigned long long)mddev->size); | 3020 | return sprintf(page, "%llu\n", |
3021 | (unsigned long long)mddev->dev_sectors / 2); | ||
3020 | } | 3022 | } |
3021 | 3023 | ||
3022 | static int update_size(mddev_t *mddev, sector_t num_sectors); | 3024 | static int update_size(mddev_t *mddev, sector_t num_sectors); |
@@ -3028,20 +3030,19 @@ size_store(mddev_t *mddev, const char *buf, size_t len) | |||
3028 | * not increase it (except from 0). | 3030 | * not increase it (except from 0). |
3029 | * If array is active, we can try an on-line resize | 3031 | * If array is active, we can try an on-line resize |
3030 | */ | 3032 | */ |
3031 | char *e; | 3033 | unsigned long long sectors; |
3032 | int err = 0; | 3034 | int err = strict_strtoull(buf, 10, §ors); |
3033 | unsigned long long size = simple_strtoull(buf, &e, 10); | ||
3034 | if (!*buf || *buf == '\n' || | ||
3035 | (*e && *e != '\n')) | ||
3036 | return -EINVAL; | ||
3037 | 3035 | ||
3036 | if (err < 0) | ||
3037 | return err; | ||
3038 | sectors *= 2; | ||
3038 | if (mddev->pers) { | 3039 | if (mddev->pers) { |
3039 | err = update_size(mddev, size * 2); | 3040 | err = update_size(mddev, sectors); |
3040 | md_update_sb(mddev, 1); | 3041 | md_update_sb(mddev, 1); |
3041 | } else { | 3042 | } else { |
3042 | if (mddev->size == 0 || | 3043 | if (mddev->dev_sectors == 0 || |
3043 | mddev->size > size) | 3044 | mddev->dev_sectors > sectors) |
3044 | mddev->size = size; | 3045 | mddev->dev_sectors = sectors; |
3045 | else | 3046 | else |
3046 | err = -ENOSPC; | 3047 | err = -ENOSPC; |
3047 | } | 3048 | } |
@@ -3306,15 +3307,15 @@ static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed); | |||
3306 | static ssize_t | 3307 | static ssize_t |
3307 | sync_completed_show(mddev_t *mddev, char *page) | 3308 | sync_completed_show(mddev_t *mddev, char *page) |
3308 | { | 3309 | { |
3309 | unsigned long max_blocks, resync; | 3310 | unsigned long max_sectors, resync; |
3310 | 3311 | ||
3311 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 3312 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) |
3312 | max_blocks = mddev->resync_max_sectors; | 3313 | max_sectors = mddev->resync_max_sectors; |
3313 | else | 3314 | else |
3314 | max_blocks = mddev->size << 1; | 3315 | max_sectors = mddev->dev_sectors; |
3315 | 3316 | ||
3316 | resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)); | 3317 | resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)); |
3317 | return sprintf(page, "%lu / %lu\n", resync, max_blocks); | 3318 | return sprintf(page, "%lu / %lu\n", resync, max_sectors); |
3318 | } | 3319 | } |
3319 | 3320 | ||
3320 | static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); | 3321 | static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); |
@@ -3789,11 +3790,11 @@ static int do_md_run(mddev_t * mddev) | |||
3789 | 3790 | ||
3790 | /* perform some consistency tests on the device. | 3791 | /* perform some consistency tests on the device. |
3791 | * We don't want the data to overlap the metadata, | 3792 | * We don't want the data to overlap the metadata, |
3792 | * Internal Bitmap issues has handled elsewhere. | 3793 | * Internal Bitmap issues have been handled elsewhere. |
3793 | */ | 3794 | */ |
3794 | if (rdev->data_offset < rdev->sb_start) { | 3795 | if (rdev->data_offset < rdev->sb_start) { |
3795 | if (mddev->size && | 3796 | if (mddev->dev_sectors && |
3796 | rdev->data_offset + mddev->size*2 | 3797 | rdev->data_offset + mddev->dev_sectors |
3797 | > rdev->sb_start) { | 3798 | > rdev->sb_start) { |
3798 | printk("md: %s: data overlaps metadata\n", | 3799 | printk("md: %s: data overlaps metadata\n", |
3799 | mdname(mddev)); | 3800 | mdname(mddev)); |
@@ -3875,7 +3876,9 @@ static int do_md_run(mddev_t * mddev) | |||
3875 | } | 3876 | } |
3876 | 3877 | ||
3877 | mddev->recovery = 0; | 3878 | mddev->recovery = 0; |
3878 | mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ | 3879 | /* may be over-ridden by personality */ |
3880 | mddev->resync_max_sectors = mddev->dev_sectors; | ||
3881 | |||
3879 | mddev->barriers_work = 1; | 3882 | mddev->barriers_work = 1; |
3880 | mddev->ok_start_degraded = start_dirty_degraded; | 3883 | mddev->ok_start_degraded = start_dirty_degraded; |
3881 | 3884 | ||
@@ -4131,7 +4134,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
4131 | export_array(mddev); | 4134 | export_array(mddev); |
4132 | 4135 | ||
4133 | mddev->array_sectors = 0; | 4136 | mddev->array_sectors = 0; |
4134 | mddev->size = 0; | 4137 | mddev->dev_sectors = 0; |
4135 | mddev->raid_disks = 0; | 4138 | mddev->raid_disks = 0; |
4136 | mddev->recovery_cp = 0; | 4139 | mddev->recovery_cp = 0; |
4137 | mddev->resync_min = 0; | 4140 | mddev->resync_min = 0; |
@@ -4337,8 +4340,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
4337 | info.patch_version = MD_PATCHLEVEL_VERSION; | 4340 | info.patch_version = MD_PATCHLEVEL_VERSION; |
4338 | info.ctime = mddev->ctime; | 4341 | info.ctime = mddev->ctime; |
4339 | info.level = mddev->level; | 4342 | info.level = mddev->level; |
4340 | info.size = mddev->size; | 4343 | info.size = mddev->dev_sectors / 2; |
4341 | if (info.size != mddev->size) /* overflow */ | 4344 | if (info.size != mddev->dev_sectors / 2) /* overflow */ |
4342 | info.size = -1; | 4345 | info.size = -1; |
4343 | info.nr_disks = nr; | 4346 | info.nr_disks = nr; |
4344 | info.raid_disks = mddev->raid_disks; | 4347 | info.raid_disks = mddev->raid_disks; |
@@ -4788,7 +4791,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
4788 | 4791 | ||
4789 | mddev->level = info->level; | 4792 | mddev->level = info->level; |
4790 | mddev->clevel[0] = 0; | 4793 | mddev->clevel[0] = 0; |
4791 | mddev->size = info->size; | 4794 | mddev->dev_sectors = 2 * (sector_t)info->size; |
4792 | mddev->raid_disks = info->raid_disks; | 4795 | mddev->raid_disks = info->raid_disks; |
4793 | /* don't set md_minor, it is determined by which /dev/md* was | 4796 | /* don't set md_minor, it is determined by which /dev/md* was |
4794 | * openned | 4797 | * openned |
@@ -4926,12 +4929,18 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
4926 | ) | 4929 | ) |
4927 | return -EINVAL; | 4930 | return -EINVAL; |
4928 | /* Check there is only one change */ | 4931 | /* Check there is only one change */ |
4929 | if (info->size >= 0 && mddev->size != info->size) cnt++; | 4932 | if (info->size >= 0 && mddev->dev_sectors / 2 != info->size) |
4930 | if (mddev->raid_disks != info->raid_disks) cnt++; | 4933 | cnt++; |
4931 | if (mddev->layout != info->layout) cnt++; | 4934 | if (mddev->raid_disks != info->raid_disks) |
4932 | if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++; | 4935 | cnt++; |
4933 | if (cnt == 0) return 0; | 4936 | if (mddev->layout != info->layout) |
4934 | if (cnt > 1) return -EINVAL; | 4937 | cnt++; |
4938 | if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) | ||
4939 | cnt++; | ||
4940 | if (cnt == 0) | ||
4941 | return 0; | ||
4942 | if (cnt > 1) | ||
4943 | return -EINVAL; | ||
4935 | 4944 | ||
4936 | if (mddev->layout != info->layout) { | 4945 | if (mddev->layout != info->layout) { |
4937 | /* Change layout | 4946 | /* Change layout |
@@ -4943,7 +4952,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
4943 | else | 4952 | else |
4944 | return mddev->pers->reconfig(mddev, info->layout, -1); | 4953 | return mddev->pers->reconfig(mddev, info->layout, -1); |
4945 | } | 4954 | } |
4946 | if (info->size >= 0 && mddev->size != info->size) | 4955 | if (info->size >= 0 && mddev->dev_sectors / 2 != info->size) |
4947 | rv = update_size(mddev, (sector_t)info->size * 2); | 4956 | rv = update_size(mddev, (sector_t)info->size * 2); |
4948 | 4957 | ||
4949 | if (mddev->raid_disks != info->raid_disks) | 4958 | if (mddev->raid_disks != info->raid_disks) |
@@ -5443,7 +5452,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev) | |||
5443 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 5452 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) |
5444 | max_blocks = mddev->resync_max_sectors >> 1; | 5453 | max_blocks = mddev->resync_max_sectors >> 1; |
5445 | else | 5454 | else |
5446 | max_blocks = mddev->size; | 5455 | max_blocks = mddev->dev_sectors / 2; |
5447 | 5456 | ||
5448 | /* | 5457 | /* |
5449 | * Should not happen. | 5458 | * Should not happen. |
@@ -6019,10 +6028,10 @@ void md_do_sync(mddev_t *mddev) | |||
6019 | j = mddev->recovery_cp; | 6028 | j = mddev->recovery_cp; |
6020 | 6029 | ||
6021 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | 6030 | } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) |
6022 | max_sectors = mddev->size << 1; | 6031 | max_sectors = mddev->dev_sectors; |
6023 | else { | 6032 | else { |
6024 | /* recovery follows the physical size of devices */ | 6033 | /* recovery follows the physical size of devices */ |
6025 | max_sectors = mddev->size << 1; | 6034 | max_sectors = mddev->dev_sectors; |
6026 | j = MaxSector; | 6035 | j = MaxSector; |
6027 | list_for_each_entry(rdev, &mddev->disks, same_set) | 6036 | list_for_each_entry(rdev, &mddev->disks, same_set) |
6028 | if (rdev->raid_disk >= 0 && | 6037 | if (rdev->raid_disk >= 0 && |