aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/md.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 86e9f2efae5c..27a9871f3057 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -695,6 +695,10 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
695 } 695 }
696 rdev->size = calc_dev_size(rdev, sb->chunk_size); 696 rdev->size = calc_dev_size(rdev, sb->chunk_size);
697 697
698 if (rdev->size < sb->size && sb->level > 1)
699 /* "this cannot possibly happen" ... */
700 ret = -EINVAL;
701
698 abort: 702 abort:
699 return ret; 703 return ret;
700} 704}
@@ -1039,6 +1043,9 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
1039 rdev->size = le64_to_cpu(sb->data_size)/2; 1043 rdev->size = le64_to_cpu(sb->data_size)/2;
1040 if (le32_to_cpu(sb->chunksize)) 1044 if (le32_to_cpu(sb->chunksize))
1041 rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1); 1045 rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
1046
1047 if (le32_to_cpu(sb->size) > rdev->size*2)
1048 return -EINVAL;
1042 return 0; 1049 return 0;
1043} 1050}
1044 1051
@@ -1224,6 +1231,14 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1224 MD_BUG(); 1231 MD_BUG();
1225 return -EINVAL; 1232 return -EINVAL;
1226 } 1233 }
1234 /* make sure rdev->size exceeds mddev->size */
1235 if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
1236 if (mddev->pers)
1237 /* Cannot change size, so fail */
1238 return -ENOSPC;
1239 else
1240 mddev->size = rdev->size;
1241 }
1227 same_pdev = match_dev_unit(mddev, rdev); 1242 same_pdev = match_dev_unit(mddev, rdev);
1228 if (same_pdev) 1243 if (same_pdev)
1229 printk(KERN_WARNING 1244 printk(KERN_WARNING
@@ -2898,12 +2913,6 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2898 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2913 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2899 set_bit(WriteMostly, &rdev->flags); 2914 set_bit(WriteMostly, &rdev->flags);
2900 2915
2901 err = bind_rdev_to_array(rdev, mddev);
2902 if (err) {
2903 export_rdev(rdev);
2904 return err;
2905 }
2906
2907 if (!mddev->persistent) { 2916 if (!mddev->persistent) {
2908 printk(KERN_INFO "md: nonpersistent superblock ...\n"); 2917 printk(KERN_INFO "md: nonpersistent superblock ...\n");
2909 rdev->sb_offset = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; 2918 rdev->sb_offset = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
@@ -2911,8 +2920,11 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2911 rdev->sb_offset = calc_dev_sboffset(rdev->bdev); 2920 rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
2912 rdev->size = calc_dev_size(rdev, mddev->chunk_size); 2921 rdev->size = calc_dev_size(rdev, mddev->chunk_size);
2913 2922
2914 if (!mddev->size || (mddev->size > rdev->size)) 2923 err = bind_rdev_to_array(rdev, mddev);
2915 mddev->size = rdev->size; 2924 if (err) {
2925 export_rdev(rdev);
2926 return err;
2927 }
2916 } 2928 }
2917 2929
2918 return 0; 2930 return 0;
@@ -2984,15 +2996,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
2984 size = calc_dev_size(rdev, mddev->chunk_size); 2996 size = calc_dev_size(rdev, mddev->chunk_size);
2985 rdev->size = size; 2997 rdev->size = size;
2986 2998
2987 if (size < mddev->size) {
2988 printk(KERN_WARNING
2989 "%s: disk size %llu blocks < array size %llu\n",
2990 mdname(mddev), (unsigned long long)size,
2991 (unsigned long long)mddev->size);
2992 err = -ENOSPC;
2993 goto abort_export;
2994 }
2995
2996 if (test_bit(Faulty, &rdev->flags)) { 2999 if (test_bit(Faulty, &rdev->flags)) {
2997 printk(KERN_WARNING 3000 printk(KERN_WARNING
2998 "md: can not hot-add faulty %s disk to %s!\n", 3001 "md: can not hot-add faulty %s disk to %s!\n",
@@ -3002,7 +3005,9 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
3002 } 3005 }
3003 clear_bit(In_sync, &rdev->flags); 3006 clear_bit(In_sync, &rdev->flags);
3004 rdev->desc_nr = -1; 3007 rdev->desc_nr = -1;
3005 bind_rdev_to_array(rdev, mddev); 3008 err = bind_rdev_to_array(rdev, mddev);
3009 if (err)
3010 goto abort_export;
3006 3011
3007 /* 3012 /*
3008 * The rest should better be atomic, we can have disk failures 3013 * The rest should better be atomic, we can have disk failures