aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-08-04 15:53:34 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-04 16:00:54 -0400
commite3b9703e27aab3839dcdb76b00d98428b67d25b0 (patch)
treef9b62479cd7062c65e54641cc6190975f529a08b /drivers/md
parent193f1c931517592ec4188d15bf261e4bff368207 (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')
-rw-r--r--drivers/md/raid1.c29
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))