diff options
Diffstat (limited to 'drivers/md/raid1.c')
| -rw-r--r-- | drivers/md/raid1.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5f253ee536bb..51d9645ed09c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -893,7 +893,6 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error) | |||
| 893 | if (!uptodate) { | 893 | if (!uptodate) { |
| 894 | md_error(r1_bio->mddev, | 894 | md_error(r1_bio->mddev, |
| 895 | conf->mirrors[r1_bio->read_disk].rdev); | 895 | conf->mirrors[r1_bio->read_disk].rdev); |
| 896 | set_bit(R1BIO_Degraded, &r1_bio->state); | ||
| 897 | } else | 896 | } else |
| 898 | set_bit(R1BIO_Uptodate, &r1_bio->state); | 897 | set_bit(R1BIO_Uptodate, &r1_bio->state); |
| 899 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); | 898 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); |
| @@ -918,10 +917,9 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) | |||
| 918 | mirror = i; | 917 | mirror = i; |
| 919 | break; | 918 | break; |
| 920 | } | 919 | } |
| 921 | if (!uptodate) { | 920 | if (!uptodate) |
| 922 | md_error(mddev, conf->mirrors[mirror].rdev); | 921 | md_error(mddev, conf->mirrors[mirror].rdev); |
| 923 | set_bit(R1BIO_Degraded, &r1_bio->state); | 922 | |
| 924 | } | ||
| 925 | update_head_pos(mirror, r1_bio); | 923 | update_head_pos(mirror, r1_bio); |
| 926 | 924 | ||
| 927 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 925 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
| @@ -1109,6 +1107,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1109 | int i; | 1107 | int i; |
| 1110 | int write_targets = 0; | 1108 | int write_targets = 0; |
| 1111 | int sync_blocks; | 1109 | int sync_blocks; |
| 1110 | int still_degraded = 0; | ||
| 1112 | 1111 | ||
| 1113 | if (!conf->r1buf_pool) | 1112 | if (!conf->r1buf_pool) |
| 1114 | { | 1113 | { |
| @@ -1137,7 +1136,10 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1137 | return 0; | 1136 | return 0; |
| 1138 | } | 1137 | } |
| 1139 | 1138 | ||
| 1140 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) && | 1139 | /* before building a request, check if we can skip these blocks.. |
| 1140 | * This call the bitmap_start_sync doesn't actually record anything | ||
| 1141 | */ | ||
| 1142 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && | ||
| 1141 | !conf->fullsync) { | 1143 | !conf->fullsync) { |
| 1142 | /* We can skip this block, and probably several more */ | 1144 | /* We can skip this block, and probably several more */ |
| 1143 | *skipped = 1; | 1145 | *skipped = 1; |
| @@ -1203,24 +1205,23 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1203 | if (i == disk) { | 1205 | if (i == disk) { |
| 1204 | bio->bi_rw = READ; | 1206 | bio->bi_rw = READ; |
| 1205 | bio->bi_end_io = end_sync_read; | 1207 | bio->bi_end_io = end_sync_read; |
| 1206 | } else if (conf->mirrors[i].rdev && | 1208 | } else if (conf->mirrors[i].rdev == NULL || |
| 1207 | !conf->mirrors[i].rdev->faulty && | 1209 | conf->mirrors[i].rdev->faulty) { |
| 1208 | (!conf->mirrors[i].rdev->in_sync || | 1210 | still_degraded = 1; |
| 1209 | sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) { | 1211 | continue; |
| 1212 | } else if (!conf->mirrors[i].rdev->in_sync || | ||
| 1213 | sector_nr + RESYNC_SECTORS > mddev->recovery_cp) { | ||
| 1210 | bio->bi_rw = WRITE; | 1214 | bio->bi_rw = WRITE; |
| 1211 | bio->bi_end_io = end_sync_write; | 1215 | bio->bi_end_io = end_sync_write; |
| 1212 | write_targets ++; | 1216 | write_targets ++; |
| 1213 | } else | 1217 | } else |
| 1218 | /* no need to read or write here */ | ||
| 1214 | continue; | 1219 | continue; |
| 1215 | bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset; | 1220 | bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset; |
| 1216 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1221 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; |
| 1217 | bio->bi_private = r1_bio; | 1222 | bio->bi_private = r1_bio; |
| 1218 | } | 1223 | } |
| 1219 | 1224 | ||
| 1220 | if (write_targets + 1 < conf->raid_disks) | ||
| 1221 | /* array degraded, can't clear bitmap */ | ||
| 1222 | set_bit(R1BIO_Degraded, &r1_bio->state); | ||
| 1223 | |||
| 1224 | if (write_targets == 0) { | 1225 | if (write_targets == 0) { |
| 1225 | /* There is nowhere to write, so all non-sync | 1226 | /* There is nowhere to write, so all non-sync |
| 1226 | * drives must be failed - so we are finished | 1227 | * drives must be failed - so we are finished |
| @@ -1243,7 +1244,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1243 | break; | 1244 | break; |
| 1244 | if (sync_blocks == 0) { | 1245 | if (sync_blocks == 0) { |
| 1245 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, | 1246 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, |
| 1246 | &sync_blocks, mddev->degraded) && | 1247 | &sync_blocks, still_degraded) && |
| 1247 | !conf->fullsync) | 1248 | !conf->fullsync) |
| 1248 | break; | 1249 | break; |
| 1249 | if (sync_blocks < (PAGE_SIZE>>9)) | 1250 | if (sync_blocks < (PAGE_SIZE>>9)) |
| @@ -1468,6 +1469,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors) | |||
| 1468 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 1469 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 1469 | } | 1470 | } |
| 1470 | mddev->size = mddev->array_size; | 1471 | mddev->size = mddev->array_size; |
| 1472 | mddev->resync_max_sectors = sectors; | ||
| 1471 | return 0; | 1473 | return 0; |
| 1472 | } | 1474 | } |
| 1473 | 1475 | ||
