diff options
Diffstat (limited to 'drivers/md/md.c')
| -rw-r--r-- | drivers/md/md.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7145cd150f7b..d05e3125d298 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1024,7 +1024,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1024 | rdev-> sb_size = (rdev->sb_size | bmask)+1; | 1024 | rdev-> sb_size = (rdev->sb_size | bmask)+1; |
| 1025 | 1025 | ||
| 1026 | if (refdev == 0) | 1026 | if (refdev == 0) |
| 1027 | return 1; | 1027 | ret = 1; |
| 1028 | else { | 1028 | else { |
| 1029 | __u64 ev1, ev2; | 1029 | __u64 ev1, ev2; |
| 1030 | struct mdp_superblock_1 *refsb = | 1030 | struct mdp_superblock_1 *refsb = |
| @@ -1044,7 +1044,9 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1044 | ev2 = le64_to_cpu(refsb->events); | 1044 | ev2 = le64_to_cpu(refsb->events); |
| 1045 | 1045 | ||
| 1046 | if (ev1 > ev2) | 1046 | if (ev1 > ev2) |
| 1047 | return 1; | 1047 | ret = 1; |
| 1048 | else | ||
| 1049 | ret = 0; | ||
| 1048 | } | 1050 | } |
| 1049 | if (minor_version) | 1051 | if (minor_version) |
| 1050 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; | 1052 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; |
| @@ -1058,7 +1060,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1058 | 1060 | ||
| 1059 | if (le32_to_cpu(sb->size) > rdev->size*2) | 1061 | if (le32_to_cpu(sb->size) > rdev->size*2) |
| 1060 | return -EINVAL; | 1062 | return -EINVAL; |
| 1061 | return 0; | 1063 | return ret; |
| 1062 | } | 1064 | } |
| 1063 | 1065 | ||
| 1064 | static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | 1066 | static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) |
| @@ -1081,7 +1083,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1081 | mddev->size = le64_to_cpu(sb->size)/2; | 1083 | mddev->size = le64_to_cpu(sb->size)/2; |
| 1082 | mddev->events = le64_to_cpu(sb->events); | 1084 | mddev->events = le64_to_cpu(sb->events); |
| 1083 | mddev->bitmap_offset = 0; | 1085 | mddev->bitmap_offset = 0; |
| 1084 | mddev->default_bitmap_offset = 1024; | 1086 | mddev->default_bitmap_offset = 1024 >> 9; |
| 1085 | 1087 | ||
| 1086 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); | 1088 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); |
| 1087 | memcpy(mddev->uuid, sb->set_uuid, 16); | 1089 | memcpy(mddev->uuid, sb->set_uuid, 16); |
| @@ -1161,6 +1163,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1161 | 1163 | ||
| 1162 | sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); | 1164 | sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); |
| 1163 | 1165 | ||
| 1166 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); | ||
| 1167 | sb->size = cpu_to_le64(mddev->size<<1); | ||
| 1168 | |||
| 1164 | if (mddev->bitmap && mddev->bitmap_file == NULL) { | 1169 | if (mddev->bitmap && mddev->bitmap_file == NULL) { |
| 1165 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); | 1170 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); |
| 1166 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); | 1171 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); |
| @@ -2686,14 +2691,6 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
| 2686 | set_disk_ro(disk, 1); | 2691 | set_disk_ro(disk, 1); |
| 2687 | } | 2692 | } |
| 2688 | 2693 | ||
| 2689 | bitmap_destroy(mddev); | ||
| 2690 | if (mddev->bitmap_file) { | ||
| 2691 | atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); | ||
| 2692 | fput(mddev->bitmap_file); | ||
| 2693 | mddev->bitmap_file = NULL; | ||
| 2694 | } | ||
| 2695 | mddev->bitmap_offset = 0; | ||
| 2696 | |||
| 2697 | /* | 2694 | /* |
| 2698 | * Free resources if final stop | 2695 | * Free resources if final stop |
| 2699 | */ | 2696 | */ |
| @@ -2703,6 +2700,14 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
| 2703 | struct gendisk *disk; | 2700 | struct gendisk *disk; |
| 2704 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); | 2701 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); |
| 2705 | 2702 | ||
| 2703 | bitmap_destroy(mddev); | ||
| 2704 | if (mddev->bitmap_file) { | ||
| 2705 | atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); | ||
| 2706 | fput(mddev->bitmap_file); | ||
| 2707 | mddev->bitmap_file = NULL; | ||
| 2708 | } | ||
| 2709 | mddev->bitmap_offset = 0; | ||
| 2710 | |||
| 2706 | ITERATE_RDEV(mddev,rdev,tmp) | 2711 | ITERATE_RDEV(mddev,rdev,tmp) |
| 2707 | if (rdev->raid_disk >= 0) { | 2712 | if (rdev->raid_disk >= 0) { |
| 2708 | char nm[20]; | 2713 | char nm[20]; |
| @@ -2939,6 +2944,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
| 2939 | info.ctime = mddev->ctime; | 2944 | info.ctime = mddev->ctime; |
| 2940 | info.level = mddev->level; | 2945 | info.level = mddev->level; |
| 2941 | info.size = mddev->size; | 2946 | info.size = mddev->size; |
| 2947 | if (info.size != mddev->size) /* overflow */ | ||
| 2948 | info.size = -1; | ||
| 2942 | info.nr_disks = nr; | 2949 | info.nr_disks = nr; |
| 2943 | info.raid_disks = mddev->raid_disks; | 2950 | info.raid_disks = mddev->raid_disks; |
| 2944 | info.md_minor = mddev->md_minor; | 2951 | info.md_minor = mddev->md_minor; |
| @@ -3465,7 +3472,7 @@ static int update_size(mddev_t *mddev, unsigned long size) | |||
| 3465 | bdev = bdget_disk(mddev->gendisk, 0); | 3472 | bdev = bdget_disk(mddev->gendisk, 0); |
| 3466 | if (bdev) { | 3473 | if (bdev) { |
| 3467 | mutex_lock(&bdev->bd_inode->i_mutex); | 3474 | mutex_lock(&bdev->bd_inode->i_mutex); |
| 3468 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | 3475 | i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10); |
| 3469 | mutex_unlock(&bdev->bd_inode->i_mutex); | 3476 | mutex_unlock(&bdev->bd_inode->i_mutex); |
| 3470 | bdput(bdev); | 3477 | bdput(bdev); |
| 3471 | } | 3478 | } |
| @@ -3485,17 +3492,6 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) | |||
| 3485 | if (mddev->sync_thread) | 3492 | if (mddev->sync_thread) |
| 3486 | return -EBUSY; | 3493 | return -EBUSY; |
| 3487 | rv = mddev->pers->reshape(mddev, raid_disks); | 3494 | rv = mddev->pers->reshape(mddev, raid_disks); |
| 3488 | if (!rv) { | ||
| 3489 | struct block_device *bdev; | ||
| 3490 | |||
| 3491 | bdev = bdget_disk(mddev->gendisk, 0); | ||
| 3492 | if (bdev) { | ||
| 3493 | mutex_lock(&bdev->bd_inode->i_mutex); | ||
| 3494 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | ||
| 3495 | mutex_unlock(&bdev->bd_inode->i_mutex); | ||
| 3496 | bdput(bdev); | ||
| 3497 | } | ||
| 3498 | } | ||
| 3499 | return rv; | 3495 | return rv; |
| 3500 | } | 3496 | } |
| 3501 | 3497 | ||
| @@ -3531,7 +3527,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
| 3531 | ) | 3527 | ) |
| 3532 | return -EINVAL; | 3528 | return -EINVAL; |
| 3533 | /* Check there is only one change */ | 3529 | /* Check there is only one change */ |
| 3534 | if (mddev->size != info->size) cnt++; | 3530 | if (info->size >= 0 && mddev->size != info->size) cnt++; |
| 3535 | if (mddev->raid_disks != info->raid_disks) cnt++; | 3531 | if (mddev->raid_disks != info->raid_disks) cnt++; |
| 3536 | if (mddev->layout != info->layout) cnt++; | 3532 | if (mddev->layout != info->layout) cnt++; |
| 3537 | if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++; | 3533 | if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++; |
| @@ -3548,7 +3544,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
| 3548 | else | 3544 | else |
| 3549 | return mddev->pers->reconfig(mddev, info->layout, -1); | 3545 | return mddev->pers->reconfig(mddev, info->layout, -1); |
| 3550 | } | 3546 | } |
| 3551 | if (mddev->size != info->size) | 3547 | if (info->size >= 0 && mddev->size != info->size) |
| 3552 | rv = update_size(mddev, info->size); | 3548 | rv = update_size(mddev, info->size); |
| 3553 | 3549 | ||
| 3554 | if (mddev->raid_disks != info->raid_disks) | 3550 | if (mddev->raid_disks != info->raid_disks) |
