diff options
Diffstat (limited to 'drivers/block/drbd/drbd_worker.c')
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 9d7e1fb0f431..1c9c6fd332c3 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -692,6 +692,7 @@ static int w_make_ov_request(struct drbd_work *w, int cancel) | |||
692 | int number, i, size; | 692 | int number, i, size; |
693 | sector_t sector; | 693 | sector_t sector; |
694 | const sector_t capacity = drbd_get_capacity(mdev->this_bdev); | 694 | const sector_t capacity = drbd_get_capacity(mdev->this_bdev); |
695 | bool stop_sector_reached = false; | ||
695 | 696 | ||
696 | if (unlikely(cancel)) | 697 | if (unlikely(cancel)) |
697 | return 1; | 698 | return 1; |
@@ -700,9 +701,17 @@ static int w_make_ov_request(struct drbd_work *w, int cancel) | |||
700 | 701 | ||
701 | sector = mdev->ov_position; | 702 | sector = mdev->ov_position; |
702 | for (i = 0; i < number; i++) { | 703 | for (i = 0; i < number; i++) { |
703 | if (sector >= capacity) { | 704 | if (sector >= capacity) |
704 | return 1; | 705 | return 1; |
705 | } | 706 | |
707 | /* We check for "finished" only in the reply path: | ||
708 | * w_e_end_ov_reply(). | ||
709 | * We need to send at least one request out. */ | ||
710 | stop_sector_reached = i > 0 | ||
711 | && verify_can_do_stop_sector(mdev) | ||
712 | && sector >= mdev->ov_stop_sector; | ||
713 | if (stop_sector_reached) | ||
714 | break; | ||
706 | 715 | ||
707 | size = BM_BLOCK_SIZE; | 716 | size = BM_BLOCK_SIZE; |
708 | 717 | ||
@@ -726,7 +735,8 @@ static int w_make_ov_request(struct drbd_work *w, int cancel) | |||
726 | 735 | ||
727 | requeue: | 736 | requeue: |
728 | mdev->rs_in_flight += (i << (BM_BLOCK_SHIFT - 9)); | 737 | mdev->rs_in_flight += (i << (BM_BLOCK_SHIFT - 9)); |
729 | mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME); | 738 | if (i == 0 || !stop_sector_reached) |
739 | mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME); | ||
730 | return 1; | 740 | return 1; |
731 | } | 741 | } |
732 | 742 | ||
@@ -792,7 +802,12 @@ int drbd_resync_finished(struct drbd_conf *mdev) | |||
792 | dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; | 802 | dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; |
793 | if (dt <= 0) | 803 | if (dt <= 0) |
794 | dt = 1; | 804 | dt = 1; |
805 | |||
795 | db = mdev->rs_total; | 806 | db = mdev->rs_total; |
807 | /* adjust for verify start and stop sectors, respective reached position */ | ||
808 | if (mdev->state.conn == C_VERIFY_S || mdev->state.conn == C_VERIFY_T) | ||
809 | db -= mdev->ov_left; | ||
810 | |||
796 | dbdt = Bit2KB(db/dt); | 811 | dbdt = Bit2KB(db/dt); |
797 | mdev->rs_paused /= HZ; | 812 | mdev->rs_paused /= HZ; |
798 | 813 | ||
@@ -815,7 +830,7 @@ int drbd_resync_finished(struct drbd_conf *mdev) | |||
815 | ns.conn = C_CONNECTED; | 830 | ns.conn = C_CONNECTED; |
816 | 831 | ||
817 | dev_info(DEV, "%s done (total %lu sec; paused %lu sec; %lu K/sec)\n", | 832 | dev_info(DEV, "%s done (total %lu sec; paused %lu sec; %lu K/sec)\n", |
818 | verify_done ? "Online verify " : "Resync", | 833 | verify_done ? "Online verify" : "Resync", |
819 | dt + mdev->rs_paused, mdev->rs_paused, dbdt); | 834 | dt + mdev->rs_paused, mdev->rs_paused, dbdt); |
820 | 835 | ||
821 | n_oos = drbd_bm_total_weight(mdev); | 836 | n_oos = drbd_bm_total_weight(mdev); |
@@ -896,7 +911,9 @@ out: | |||
896 | mdev->rs_total = 0; | 911 | mdev->rs_total = 0; |
897 | mdev->rs_failed = 0; | 912 | mdev->rs_failed = 0; |
898 | mdev->rs_paused = 0; | 913 | mdev->rs_paused = 0; |
899 | if (verify_done) | 914 | |
915 | /* reset start sector, if we reached end of device */ | ||
916 | if (verify_done && mdev->ov_left == 0) | ||
900 | mdev->ov_start_sector = 0; | 917 | mdev->ov_start_sector = 0; |
901 | 918 | ||
902 | drbd_md_sync(mdev); | 919 | drbd_md_sync(mdev); |
@@ -1144,6 +1161,7 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel) | |||
1144 | unsigned int size = peer_req->i.size; | 1161 | unsigned int size = peer_req->i.size; |
1145 | int digest_size; | 1162 | int digest_size; |
1146 | int err, eq = 0; | 1163 | int err, eq = 0; |
1164 | bool stop_sector_reached = false; | ||
1147 | 1165 | ||
1148 | if (unlikely(cancel)) { | 1166 | if (unlikely(cancel)) { |
1149 | drbd_free_peer_req(mdev, peer_req); | 1167 | drbd_free_peer_req(mdev, peer_req); |
@@ -1194,7 +1212,10 @@ int w_e_end_ov_reply(struct drbd_work *w, int cancel) | |||
1194 | if ((mdev->ov_left & 0x200) == 0x200) | 1212 | if ((mdev->ov_left & 0x200) == 0x200) |
1195 | drbd_advance_rs_marks(mdev, mdev->ov_left); | 1213 | drbd_advance_rs_marks(mdev, mdev->ov_left); |
1196 | 1214 | ||
1197 | if (mdev->ov_left == 0) { | 1215 | stop_sector_reached = verify_can_do_stop_sector(mdev) && |
1216 | (sector + (size>>9)) >= mdev->ov_stop_sector; | ||
1217 | |||
1218 | if (mdev->ov_left == 0 || stop_sector_reached) { | ||
1198 | ov_out_of_sync_print(mdev); | 1219 | ov_out_of_sync_print(mdev); |
1199 | drbd_resync_finished(mdev); | 1220 | drbd_resync_finished(mdev); |
1200 | } | 1221 | } |