Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'md/4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md

Pull MD fixes from Shaohua Li:
"There are several bug fixes queued:

- fix raid5-cache recovery bugs

- fix discard IO error handling for raid1/10

- fix array sync writes bogus position to superblock

- fix IO error handling for raid array with external metadata"

* tag 'md/4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/shli/md:
md: be careful not lot leak internal curr_resync value into metadata. -- (all)
raid1: handle read error also in readonly mode
raid5-cache: correct condition for empty metadata write
md: report 'write_pending' state when array in sync
md/raid5: write an empty meta-block when creating log super-block
md/raid5: initialize next_checkpoint field before use
RAID10: ignore discard error
RAID1: ignore discard error

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