diff options
| -rw-r--r-- | drivers/md/md-cluster.c | 47 | ||||
| -rw-r--r-- | drivers/md/md.c | 17 | ||||
| -rw-r--r-- | drivers/md/md.h | 1 | ||||
| -rw-r--r-- | drivers/md/raid5-cache.c | 2 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 12 |
5 files changed, 61 insertions, 18 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 021cbf9ef1bf..e8a74e92be30 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c | |||
| @@ -304,15 +304,6 @@ static void recover_bitmaps(struct md_thread *thread) | |||
| 304 | while (cinfo->recovery_map) { | 304 | while (cinfo->recovery_map) { |
| 305 | slot = fls64((u64)cinfo->recovery_map) - 1; | 305 | slot = fls64((u64)cinfo->recovery_map) - 1; |
| 306 | 306 | ||
| 307 | /* Clear suspend_area associated with the bitmap */ | ||
| 308 | spin_lock_irq(&cinfo->suspend_lock); | ||
| 309 | list_for_each_entry_safe(s, tmp, &cinfo->suspend_list, list) | ||
| 310 | if (slot == s->slot) { | ||
| 311 | list_del(&s->list); | ||
| 312 | kfree(s); | ||
| 313 | } | ||
| 314 | spin_unlock_irq(&cinfo->suspend_lock); | ||
| 315 | |||
| 316 | snprintf(str, 64, "bitmap%04d", slot); | 307 | snprintf(str, 64, "bitmap%04d", slot); |
| 317 | bm_lockres = lockres_init(mddev, str, NULL, 1); | 308 | bm_lockres = lockres_init(mddev, str, NULL, 1); |
| 318 | if (!bm_lockres) { | 309 | if (!bm_lockres) { |
| @@ -331,14 +322,30 @@ static void recover_bitmaps(struct md_thread *thread) | |||
| 331 | pr_err("md-cluster: Could not copy data from bitmap %d\n", slot); | 322 | pr_err("md-cluster: Could not copy data from bitmap %d\n", slot); |
| 332 | goto clear_bit; | 323 | goto clear_bit; |
| 333 | } | 324 | } |
| 325 | |||
| 326 | /* Clear suspend_area associated with the bitmap */ | ||
| 327 | spin_lock_irq(&cinfo->suspend_lock); | ||
| 328 | list_for_each_entry_safe(s, tmp, &cinfo->suspend_list, list) | ||
| 329 | if (slot == s->slot) { | ||
| 330 | list_del(&s->list); | ||
| 331 | kfree(s); | ||
| 332 | } | ||
| 333 | spin_unlock_irq(&cinfo->suspend_lock); | ||
| 334 | |||
| 334 | if (hi > 0) { | 335 | if (hi > 0) { |
| 335 | if (lo < mddev->recovery_cp) | 336 | if (lo < mddev->recovery_cp) |
| 336 | mddev->recovery_cp = lo; | 337 | mddev->recovery_cp = lo; |
| 337 | /* wake up thread to continue resync in case resync | 338 | /* wake up thread to continue resync in case resync |
| 338 | * is not finished */ | 339 | * is not finished */ |
| 339 | if (mddev->recovery_cp != MaxSector) { | 340 | if (mddev->recovery_cp != MaxSector) { |
| 340 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 341 | /* |
| 341 | md_wakeup_thread(mddev->thread); | 342 | * clear the REMOTE flag since we will launch |
| 343 | * resync thread in current node. | ||
| 344 | */ | ||
| 345 | clear_bit(MD_RESYNCING_REMOTE, | ||
| 346 | &mddev->recovery); | ||
| 347 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
| 348 | md_wakeup_thread(mddev->thread); | ||
| 342 | } | 349 | } |
| 343 | } | 350 | } |
| 344 | clear_bit: | 351 | clear_bit: |
| @@ -457,6 +464,11 @@ static void process_suspend_info(struct mddev *mddev, | |||
| 457 | struct suspend_info *s; | 464 | struct suspend_info *s; |
| 458 | 465 | ||
| 459 | if (!hi) { | 466 | if (!hi) { |
| 467 | /* | ||
| 468 | * clear the REMOTE flag since resync or recovery is finished | ||
| 469 | * in remote node. | ||
| 470 | */ | ||
| 471 | clear_bit(MD_RESYNCING_REMOTE, &mddev->recovery); | ||
| 460 | remove_suspend_info(mddev, slot); | 472 | remove_suspend_info(mddev, slot); |
| 461 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 473 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 462 | md_wakeup_thread(mddev->thread); | 474 | md_wakeup_thread(mddev->thread); |
| @@ -585,6 +597,7 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg) | |||
| 585 | revalidate_disk(mddev->gendisk); | 597 | revalidate_disk(mddev->gendisk); |
| 586 | break; | 598 | break; |
| 587 | case RESYNCING: | 599 | case RESYNCING: |
| 600 | set_bit(MD_RESYNCING_REMOTE, &mddev->recovery); | ||
| 588 | process_suspend_info(mddev, le32_to_cpu(msg->slot), | 601 | process_suspend_info(mddev, le32_to_cpu(msg->slot), |
| 589 | le64_to_cpu(msg->low), | 602 | le64_to_cpu(msg->low), |
| 590 | le64_to_cpu(msg->high)); | 603 | le64_to_cpu(msg->high)); |
| @@ -1265,8 +1278,18 @@ static int resync_info_update(struct mddev *mddev, sector_t lo, sector_t hi) | |||
| 1265 | static int resync_finish(struct mddev *mddev) | 1278 | static int resync_finish(struct mddev *mddev) |
| 1266 | { | 1279 | { |
| 1267 | struct md_cluster_info *cinfo = mddev->cluster_info; | 1280 | struct md_cluster_info *cinfo = mddev->cluster_info; |
| 1281 | |||
| 1282 | clear_bit(MD_RESYNCING_REMOTE, &mddev->recovery); | ||
| 1268 | dlm_unlock_sync(cinfo->resync_lockres); | 1283 | dlm_unlock_sync(cinfo->resync_lockres); |
| 1269 | return resync_info_update(mddev, 0, 0); | 1284 | |
| 1285 | /* | ||
| 1286 | * If resync thread is interrupted so we can't say resync is finished, | ||
| 1287 | * another node will launch resync thread to continue. | ||
| 1288 | */ | ||
| 1289 | if (test_bit(MD_CLOSING, &mddev->flags)) | ||
| 1290 | return 0; | ||
| 1291 | else | ||
| 1292 | return resync_info_update(mddev, 0, 0); | ||
| 1270 | } | 1293 | } |
| 1271 | 1294 | ||
| 1272 | static int area_resyncing(struct mddev *mddev, int direction, | 1295 | static int area_resyncing(struct mddev *mddev, int direction, |
diff --git a/drivers/md/md.c b/drivers/md/md.c index cb4eb5faa519..724def2f9eaa 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -7677,6 +7677,23 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev) | |||
| 7677 | resync -= atomic_read(&mddev->recovery_active); | 7677 | resync -= atomic_read(&mddev->recovery_active); |
| 7678 | 7678 | ||
| 7679 | if (resync == 0) { | 7679 | if (resync == 0) { |
| 7680 | if (test_bit(MD_RESYNCING_REMOTE, &mddev->recovery)) { | ||
| 7681 | struct md_rdev *rdev; | ||
| 7682 | |||
| 7683 | rdev_for_each(rdev, mddev) | ||
| 7684 | if (rdev->raid_disk >= 0 && | ||
| 7685 | !test_bit(Faulty, &rdev->flags) && | ||
| 7686 | rdev->recovery_offset != MaxSector && | ||
| 7687 | rdev->recovery_offset) { | ||
| 7688 | seq_printf(seq, "\trecover=REMOTE"); | ||
| 7689 | return 1; | ||
| 7690 | } | ||
| 7691 | if (mddev->reshape_position != MaxSector) | ||
| 7692 | seq_printf(seq, "\treshape=REMOTE"); | ||
| 7693 | else | ||
| 7694 | seq_printf(seq, "\tresync=REMOTE"); | ||
| 7695 | return 1; | ||
| 7696 | } | ||
| 7680 | if (mddev->recovery_cp < MaxSector) { | 7697 | if (mddev->recovery_cp < MaxSector) { |
| 7681 | seq_printf(seq, "\tresync=PENDING"); | 7698 | seq_printf(seq, "\tresync=PENDING"); |
| 7682 | return 1; | 7699 | return 1; |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 2d148bdaba74..8afd6bfdbfb9 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
| @@ -496,6 +496,7 @@ enum recovery_flags { | |||
| 496 | MD_RECOVERY_FROZEN, /* User request to abort, and not restart, any action */ | 496 | MD_RECOVERY_FROZEN, /* User request to abort, and not restart, any action */ |
| 497 | MD_RECOVERY_ERROR, /* sync-action interrupted because io-error */ | 497 | MD_RECOVERY_ERROR, /* sync-action interrupted because io-error */ |
| 498 | MD_RECOVERY_WAIT, /* waiting for pers->start() to finish */ | 498 | MD_RECOVERY_WAIT, /* waiting for pers->start() to finish */ |
| 499 | MD_RESYNCING_REMOTE, /* remote node is running resync thread */ | ||
| 499 | }; | 500 | }; |
| 500 | 501 | ||
| 501 | static inline int __must_check mddev_lock(struct mddev *mddev) | 502 | static inline int __must_check mddev_lock(struct mddev *mddev) |
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index 2b775abf377b..7416db70c6cc 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c | |||
| @@ -717,7 +717,6 @@ static void r5c_disable_writeback_async(struct work_struct *work) | |||
| 717 | static void r5l_submit_current_io(struct r5l_log *log) | 717 | static void r5l_submit_current_io(struct r5l_log *log) |
| 718 | { | 718 | { |
| 719 | struct r5l_io_unit *io = log->current_io; | 719 | struct r5l_io_unit *io = log->current_io; |
| 720 | struct bio *bio; | ||
| 721 | struct r5l_meta_block *block; | 720 | struct r5l_meta_block *block; |
| 722 | unsigned long flags; | 721 | unsigned long flags; |
| 723 | u32 crc; | 722 | u32 crc; |
| @@ -730,7 +729,6 @@ static void r5l_submit_current_io(struct r5l_log *log) | |||
| 730 | block->meta_size = cpu_to_le32(io->meta_offset); | 729 | block->meta_size = cpu_to_le32(io->meta_offset); |
| 731 | crc = crc32c_le(log->uuid_checksum, block, PAGE_SIZE); | 730 | crc = crc32c_le(log->uuid_checksum, block, PAGE_SIZE); |
| 732 | block->checksum = cpu_to_le32(crc); | 731 | block->checksum = cpu_to_le32(crc); |
| 733 | bio = io->current_bio; | ||
| 734 | 732 | ||
| 735 | log->current_io = NULL; | 733 | log->current_io = NULL; |
| 736 | spin_lock_irqsave(&log->io_list_lock, flags); | 734 | spin_lock_irqsave(&log->io_list_lock, flags); |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 2031506a0ecd..81eaa221216c 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -409,16 +409,14 @@ void raid5_release_stripe(struct stripe_head *sh) | |||
| 409 | md_wakeup_thread(conf->mddev->thread); | 409 | md_wakeup_thread(conf->mddev->thread); |
| 410 | return; | 410 | return; |
| 411 | slow_path: | 411 | slow_path: |
| 412 | local_irq_save(flags); | ||
| 413 | /* we are ok here if STRIPE_ON_RELEASE_LIST is set or not */ | 412 | /* we are ok here if STRIPE_ON_RELEASE_LIST is set or not */ |
| 414 | if (atomic_dec_and_lock(&sh->count, &conf->device_lock)) { | 413 | if (atomic_dec_and_lock_irqsave(&sh->count, &conf->device_lock, flags)) { |
| 415 | INIT_LIST_HEAD(&list); | 414 | INIT_LIST_HEAD(&list); |
| 416 | hash = sh->hash_lock_index; | 415 | hash = sh->hash_lock_index; |
| 417 | do_release_stripe(conf, sh, &list); | 416 | do_release_stripe(conf, sh, &list); |
| 418 | spin_unlock(&conf->device_lock); | 417 | spin_unlock_irqrestore(&conf->device_lock, flags); |
| 419 | release_inactive_stripe_list(conf, &list, hash); | 418 | release_inactive_stripe_list(conf, &list, hash); |
| 420 | } | 419 | } |
| 421 | local_irq_restore(flags); | ||
| 422 | } | 420 | } |
| 423 | 421 | ||
| 424 | static inline void remove_hash(struct stripe_head *sh) | 422 | static inline void remove_hash(struct stripe_head *sh) |
| @@ -4521,6 +4519,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
| 4521 | s->failed++; | 4519 | s->failed++; |
| 4522 | if (rdev && !test_bit(Faulty, &rdev->flags)) | 4520 | if (rdev && !test_bit(Faulty, &rdev->flags)) |
| 4523 | do_recovery = 1; | 4521 | |
