aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/md-cluster.c47
-rw-r--r--drivers/md/md.c17
-rw-r--r--drivers/md/md.h1
-rw-r--r--drivers/md/raid5-cache.c2
-rw-r--r--drivers/md/raid5.c12
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 }
344clear_bit: 351clear_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)
1265static int resync_finish(struct mddev *mddev) 1278static 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
1272static int area_resyncing(struct mddev *mddev, int direction, 1295static 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
501static inline int __must_check mddev_lock(struct mddev *mddev) 502static 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)
717static void r5l_submit_current_io(struct r5l_log *log) 717static 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;
411slow_path: 411slow_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
424static inline void remove_hash(struct stripe_head *sh) 422static 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