diff options
| author | NeilBrown <neilb@cse.unsw.edu.au> | 2005-08-04 15:53:34 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-04 16:00:54 -0400 |
| commit | e3b9703e27aab3839dcdb76b00d98428b67d25b0 (patch) | |
| tree | f9b62479cd7062c65e54641cc6190975f529a08b /drivers/md/raid1.c | |
| parent | 193f1c931517592ec4188d15bf261e4bff368207 (diff) | |
[PATCH] md: yet another attempt to get bitmap-based resync to do the right thing in all cases...
Firstly, R1BIO_Degraded was being set in a number of places in the resync
code, but is never used there, so get rid of those settings.
Then: When doing a resync, we want to clear the bit in the bitmap iff the
array will be non-degraded when the sync has completed. However the current
code would clear the bitmap if the array was non-degraded when the resync
*started*, which obviously isn't right (it is for 'resync' but not for
'recovery' - i.e. rebuilding a failed drive).
This patch calculated 'still_degraded' and uses the to tell bitmap_start_sync
whether this sync should clear the corresponding bit.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/raid1.c')
| -rw-r--r-- | drivers/md/raid1.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d3a64a04a6d8..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)) |
