diff options
| -rw-r--r-- | drivers/md/md.c | 10 | ||||
| -rw-r--r-- | drivers/md/raid1.c | 26 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 7 | ||||
| -rw-r--r-- | drivers/md/raid5-cache.c | 6 |
4 files changed, 30 insertions, 19 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index eac84d8ff724..2089d46b0eb8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -3887,10 +3887,10 @@ array_state_show(struct mddev *mddev, char *page) | |||
| 3887 | st = read_auto; | 3887 | st = read_auto; |
| 3888 | break; | 3888 | break; |
| 3889 | case 0: | 3889 | case 0: |
| 3890 | if (mddev->in_sync) | 3890 | if (test_bit(MD_CHANGE_PENDING, &mddev->flags)) |
| 3891 | st = clean; | ||
| 3892 | else if (test_bit(MD_CHANGE_PENDING, &mddev->flags)) | ||
| 3893 | st = write_pending; | 3891 | st = write_pending; |
| 3892 | else if (mddev->in_sync) | ||
| 3893 | st = clean; | ||
| 3894 | else if (mddev->safemode) | 3894 | else if (mddev->safemode) |
| 3895 | st = active_idle; | 3895 | st = active_idle; |
| 3896 | else | 3896 | else |
| @@ -8144,14 +8144,14 @@ void md_do_sync(struct md_thread *thread) | |||
| 8144 | 8144 | ||
| 8145 | if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && | 8145 | if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && |
| 8146 | !test_bit(MD_RECOVERY_INTR, &mddev->recovery) && | 8146 | !test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
| 8147 | mddev->curr_resync > 2) { | 8147 | mddev->curr_resync > 3) { |
| 8148 | mddev->curr_resync_completed = mddev->curr_resync; | 8148 | mddev->curr_resync_completed = mddev->curr_resync; |
| 8149 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 8149 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
| 8150 | } | 8150 | } |
| 8151 | mddev->pers->sync_request(mddev, max_sectors, &skipped); | 8151 | mddev->pers->sync_request(mddev, max_sectors, &skipped); |
| 8152 | 8152 | ||
| 8153 | if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && | 8153 | if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) && |
| 8154 | mddev->curr_resync > 2) { | 8154 | mddev->curr_resync > 3) { |
| 8155 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { | 8155 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { |
| 8156 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | 8156 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { |
| 8157 | if (mddev->curr_resync >= mddev->recovery_cp) { | 8157 | if (mddev->curr_resync >= mddev->recovery_cp) { |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1961d827dbd1..29e2df5cd77b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -403,11 +403,14 @@ static void raid1_end_write_request(struct bio *bio) | |||
| 403 | struct bio *to_put = NULL; | 403 | struct bio *to_put = NULL; |
| 404 | int mirror = find_bio_disk(r1_bio, bio); | 404 | int mirror = find_bio_disk(r1_bio, bio); |
| 405 | struct md_rdev *rdev = conf->mirrors[mirror].rdev; | 405 | struct md_rdev *rdev = conf->mirrors[mirror].rdev; |
| 406 | bool discard_error; | ||
| 407 | |||
| 408 | discard_error = bio->bi_error && bio_op(bio) == REQ_OP_DISCARD; | ||
| 406 | 409 | ||
| 407 | /* | 410 | /* |
| 408 | * 'one mirror IO has finished' event handler: | 411 | * 'one mirror IO has finished' event handler: |
| 409 | */ | 412 | */ |
| 410 | if (bio->bi_error) { | 413 | if (bio->bi_error && !discard_error) { |
| 411 | set_bit(WriteErrorSeen, &rdev->flags); | 414 | set_bit(WriteErrorSeen, &rdev->flags); |
| 412 | if (!test_and_set_bit(WantReplacement, &rdev->flags)) | 415 | if (!test_and_set_bit(WantReplacement, &rdev->flags)) |
| 413 | set_bit(MD_RECOVERY_NEEDED, & | 416 | set_bit(MD_RECOVERY_NEEDED, & |
| @@ -444,7 +447,7 @@ static void raid1_end_write_request(struct bio *bio) | |||
| 444 | 447 | ||
| 445 | /* Maybe we can clear some bad blocks. */ | 448 | /* Maybe we can clear some bad blocks. */ |
| 446 | if (is_badblock(rdev, r1_bio->sector, r1_bio->sectors, | 449 | if (is_badblock(rdev, r1_bio->sector, r1_bio->sectors, |
| 447 | &first_bad, &bad_sectors)) { | 450 | &first_bad, &bad_sectors) && !discard_error) { |
| 448 | r1_bio->bios[mirror] = IO_MADE_GOOD; | 451 | r1_bio->bios[mirror] = IO_MADE_GOOD; |
| 449 | set_bit(R1BIO_MadeGood, &r1_bio->state); | 452 | set_bit(R1BIO_MadeGood, &r1_bio->state); |
| 450 | } | 453 | } |
| @@ -2294,17 +2297,23 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) | |||
| 2294 | * This is all done synchronously while the array is | 2297 | * This is all done synchronously while the array is |
| 2295 | * frozen | 2298 | * frozen |
| 2296 | */ | 2299 | */ |
| 2300 | |||
| 2301 | bio = r1_bio->bios[r1_bio->read_disk]; | ||
| 2302 | bdevname(bio->bi_bdev, b); | ||
| 2303 | bio_put(bio); | ||
| 2304 | r1_bio->bios[r1_bio->read_disk] = NULL; | ||
| 2305 | |||
| 2297 | if (mddev->ro == 0) { | 2306 | if (mddev->ro == 0) { |
| 2298 | freeze_array(conf, 1); | 2307 | freeze_array(conf, 1); |
| 2299 | fix_read_error(conf, r1_bio->read_disk, | 2308 | fix_read_error(conf, r1_bio->read_disk, |
| 2300 | r1_bio->sector, r1_bio->sectors); | 2309 | r1_bio->sector, r1_bio->sectors); |
| 2301 | unfreeze_array(conf); | 2310 | unfreeze_array(conf); |
| 2302 | } else | 2311 | } else { |
| 2303 | md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev); | 2312 | r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED; |
| 2313 | } | ||
| 2314 | |||
| 2304 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); | 2315 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); |
| 2305 | 2316 | ||
| 2306 | bio = r1_bio->bios[r1_bio->read_disk]; | ||
| 2307 | bdevname(bio->bi_bdev, b); | ||
| 2308 | read_more: | 2317 | read_more: |
| 2309 | disk = read_balance(conf, r1_bio, &max_sectors); | 2318 | disk = read_balance(conf, r1_bio, &max_sectors); |
| 2310 | if (disk == -1) { | 2319 | if (disk == -1) { |
| @@ -2315,11 +2324,6 @@ read_more: | |||
| 2315 | } else { | 2324 | } else { |
| 2316 | const unsigned long do_sync | 2325 | const unsigned long do_sync |
| 2317 | = r1_bio->master_bio->bi_opf & REQ_SYNC; | 2326 | = r1_bio->master_bio->bi_opf & REQ_SYNC; |
| 2318 | if (bio) { | ||
| 2319 | r1_bio->bios[r1_bio->read_disk] = | ||
| 2320 | mddev->ro ? IO_BLOCKED : NULL; | ||
| 2321 | bio_put(bio); | ||
| 2322 | } | ||
| 2323 | r1_bio->read_disk = disk; | 2327 | r1_bio->read_disk = disk; |
| 2324 | bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev); | 2328 | bio = bio_clone_mddev(r1_bio->master_bio, GFP_NOIO, mddev); |
| 2325 | bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector, | 2329 | bio_trim(bio, r1_bio->sector - bio->bi_iter.bi_sector, |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index be1a9fca3b2d..39fddda2fef2 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -447,6 +447,9 @@ static void raid10_end_write_request(struct bio *bio) | |||
| 447 | struct r10conf *conf = r10_bio->mddev->private; | 447 | struct r10conf *conf = r10_bio->mddev->private; |
| 448 | int slot, repl; | 448 | int slot, repl; |
| 449 | struct md_rdev *rdev = NULL; | 449 | struct md_rdev *rdev = NULL; |
| 450 | bool discard_error; | ||
| 451 | |||
| 452 | discard_error = bio->bi_error && bio_op(bio) == REQ_OP_DISCARD; | ||
| 450 | 453 | ||
| 451 | dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl); | 454 | dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl); |
| 452 | 455 | ||
| @@ -460,7 +463,7 @@ static void raid10_end_write_request(struct bio *bio) | |||
| 460 | /* | 463 | /* |
| 461 | * this branch is our 'one mirror IO has finished' event handler: | 464 | * this branch is our 'one mirror IO has finished' event handler: |
| 462 | */ | 465 | */ |
| 463 | if (bio->bi_error) { | 466 | if (bio->bi_error && !discard_error) { |
| 464 | if (repl) | 467 | if (repl) |
| 465 | /* Never record new bad blocks to replacement, | 468 | /* Never record new bad blocks to replacement, |
| 466 | * just fail it. | 469 | * just fail it. |
| @@ -503,7 +506,7 @@ static void raid10_end_write_request(struct bio *bio) | |||
| 503 | if (is_badblock(rdev, | 506 | if (is_badblock(rdev, |
| 504 | r10_bio->devs[slot].addr, | 507 | r10_bio->devs[slot].addr, |
| 505 | r10_bio->sectors, | 508 | r10_bio->sectors, |
| 506 | &first_bad, &bad_sectors)) { | 509 | &first_bad, &bad_sectors) && !discard_error) { |
| 507 | bio_put(bio); | 510 | bio_put(bio); |
| 508 | if (repl) | 511 | if (repl) |
| 509 | r10_bio->devs[slot].repl_bio = IO_MADE_GOOD; | 512 | r10_bio->devs[slot].repl_bio = IO_MADE_GOOD; |
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 1b1ab4a1d132..a227a9f3ee65 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c | |||
| @@ -1087,7 +1087,7 @@ static int r5l_recovery_log(struct r5l_log *log) | |||
| 1087 | * 1's seq + 10 and let superblock points to meta2. The same recovery will | 1087 | * 1's seq + 10 and let superblock points to meta2. The same recovery will |
| 1088 | * not think meta 3 is a valid meta, because its seq doesn't match | 1088 | * not think meta 3 is a valid meta, because its seq doesn't match |
| 1089 | */ | 1089 | */ |
| 1090 | if (ctx.seq > log->last_cp_seq + 1) { | 1090 | if (ctx.seq > log->last_cp_seq) { |
| 1091 | int ret; | 1091 | int ret; |
| 1092 | 1092 | ||
| 1093 | ret = r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq + 10); | 1093 | ret = r5l_log_write_empty_meta_block(log, ctx.pos, ctx.seq + 10); |
| @@ -1096,6 +1096,8 @@ static int r5l_recovery_log(struct r5l_log *log) | |||
| 1096 | log->seq = ctx.seq + 11; | 1096 | log->seq = ctx.seq + 11; |
| 1097 | log->log_start = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS); | 1097 | log->log_start = r5l_ring_add(log, ctx.pos, BLOCK_SECTORS); |
| 1098 | r5l_write_super(log, ctx.pos); | 1098 | r5l_write_super(log, ctx.pos); |
| 1099 | log->last_checkpoint = ctx.pos; | ||
| 1100 | log->next_checkpoint = ctx.pos; | ||
| 1099 | } else { | 1101 | } else { |
| 1100 | log->log_start = ctx.pos; | 1102 | log->log_start = ctx.pos; |
| 1101 | log->seq = ctx.seq; | 1103 | log->seq = ctx.seq; |
| @@ -1154,6 +1156,7 @@ create: | |||
| 1154 | if (create_super) { | 1156 | if (create_super) { |
| 1155 | log->last_cp_seq = prandom_u32(); | 1157 | log->last_cp_seq = prandom_u32(); |
| 1156 | cp = 0; | 1158 | cp = 0; |
| 1159 | r5l_log_write_empty_meta_block(log, cp, log->last_cp_seq); | ||
| 1157 | /* | 1160 | /* |
| 1158 | * Make sure super points to correct address. Log might have | 1161 | * Make sure super points to correct address. Log might have |
| 1159 | * data very soon. If super hasn't correct log tail address, | 1162 | * data very soon. If super hasn't correct log tail address, |
| @@ -1168,6 +1171,7 @@ create: | |||
| 1168 | if (log->max_free_space > RECLAIM_MAX_FREE_SPACE) | 1171 | if (log->max_free_space > RECLAIM_MAX_FREE_SPACE) |
| 1169 | log->max_free_space = RECLAIM_MAX_FREE_SPACE; | 1172 | log->max_free_space = RECLAIM_MAX_FREE_SPACE; |
| 1170 | log->last_checkpoint = cp; | 1173 | log->last_checkpoint = cp; |
| 1174 | log->next_checkpoint = cp; | ||
| 1171 | 1175 | ||
| 1172 | __free_page(page); | 1176 | __free_page(page); |
| 1173 | 1177 | ||
