From 0d18e050108789a6907a8a19f3eb84ec96c18e11 Mon Sep 17 00:00:00 2001
From: Lars Ellenberg <lars.ellenberg@linbit.com>
Date: Fri, 4 May 2018 11:57:01 +0200
Subject: [PATCH] drbd: re-introduce "occasional" resync/verify progress
 broadcasts

These will be visible via events2 --statistics
---
 drbd/drbd_actlog.c   |  3 ++-
 drbd/drbd_int.h      |  2 ++
 drbd/drbd_nl.c       | 10 ++++++++++
 drbd/drbd_receiver.c |  3 ++-
 drbd/drbd_sender.c   |  6 ++++--
 drbd/drbd_state.c    |  3 ++-
 6 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drbd/drbd_actlog.c b/drbd/drbd_actlog.c
index e0bdb36928c1..3ce8cc1f11d3 100644
--- a/drbd/drbd_actlog.c
+++ b/drbd/drbd_actlog.c
@@ -976,6 +976,7 @@ void drbd_advance_rs_marks(struct drbd_peer_device *peer_device, unsigned long s
 			peer_device->rs_mark_left[next] = still_to_go;
 			peer_device->rs_last_mark = next;
 		}
+		drbd_peer_device_post_work(peer_device, RS_PROGRESS);
 	}
 }
 
@@ -1001,7 +1002,7 @@ static void maybe_schedule_on_disk_bitmap_update(struct drbd_peer_device *peer_d
 	} else if (!lazy_bitmap_update_due(peer_device))
 		return;
 
-	drbd_peer_device_post_work(peer_device, RS_PROGRESS);
+	drbd_peer_device_post_work(peer_device, RS_LAZY_BM_WRITE);
 }
 
 
diff --git a/drbd/drbd_int.h b/drbd/drbd_int.h
index 527e3361c177..1335639c7f82 100644
--- a/drbd/drbd_int.h
+++ b/drbd/drbd_int.h
@@ -561,6 +561,7 @@ enum {
 				 * the peer, if it changed there as well. */
 	RS_START,		/* tell worker to start resync/OV */
 	RS_PROGRESS,		/* tell worker that resync made significant progress */
+	RS_LAZY_BM_WRITE,	/*  -"- and bitmap writeout should be efficient now */
 	RS_DONE,		/* tell worker that resync is done */
 	B_RS_H_DONE,		/* Before resync handler done (already executed) */
 	DISCARD_MY_DATA,	/* discard_my_data flag per volume */
@@ -2097,6 +2098,7 @@ extern void notify_helper(enum drbd_notification_type, struct drbd_device *,
 			  struct drbd_connection *, const char *, int);
 extern void notify_path(struct drbd_connection *, struct drbd_path *,
 			enum drbd_notification_type);
+extern void drbd_broadcast_sync_progress(struct drbd_peer_device *);
 
 extern sector_t drbd_local_max_size(struct drbd_device *device) __must_hold(local);
 extern int drbd_open_ro_count(struct drbd_resource *resource);
diff --git a/drbd/drbd_nl.c b/drbd/drbd_nl.c
index 8ef570c966c2..8cc8fc9dcdbd 100644
--- a/drbd/drbd_nl.c
+++ b/drbd/drbd_nl.c
@@ -6145,6 +6145,16 @@ failed:
 		 err, seq);
 }
 
+void drbd_broadcast_sync_progress(struct drbd_peer_device *peer_device)
+{
+	struct peer_device_info peer_device_info;
+	mutex_lock(&notification_mutex);
+	peer_device_to_info(&peer_device_info, peer_device);
+	/* XXX maybe we want a .nh_type = NOTIFY_RESYNC_PROGRESS or something? */
+	notify_peer_device_state(NULL, 0, peer_device, &peer_device_info, NOTIFY_CHANGE);
+	mutex_unlock(&notification_mutex);
+}
+
 void notify_path(struct drbd_connection *connection, struct drbd_path *path,
 		 enum drbd_notification_type type)
 {
diff --git a/drbd/drbd_receiver.c b/drbd/drbd_receiver.c
index 8db10eaf086f..a9869bf02918 100644
--- a/drbd/drbd_receiver.c
+++ b/drbd/drbd_receiver.c
@@ -3087,15 +3087,16 @@ static int receive_DataRequest(struct drbd_connection *connection, struct packet
 		break;
 
 	case P_OV_REQUEST:
+		peer_device->ov_position = sector;
 		if (peer_device->ov_start_sector == ~(sector_t)0 &&
 		    connection->agreed_pro_version >= 90) {
 			unsigned long now = jiffies;
 			int i;
 			peer_device->ov_start_sector = sector;
-			peer_device->ov_position = sector;
 			peer_device->ov_left = drbd_bm_bits(device) - BM_SECT_TO_BIT(sector);
 			peer_device->ov_skipped = 0;
 			peer_device->rs_total = peer_device->ov_left;
+			peer_device->rs_last_writeout = now;
 			for (i = 0; i < DRBD_SYNC_MARKS; i++) {
 				peer_device->rs_mark_left[i] = peer_device->ov_left;
 				peer_device->rs_mark_time[i] = now;
diff --git a/drbd/drbd_sender.c b/drbd/drbd_sender.c
index 341c8e84db0b..f2a39b9ce805 100644
--- a/drbd/drbd_sender.c
+++ b/drbd/drbd_sender.c
@@ -2091,7 +2091,6 @@ static void update_on_disk_bitmap(struct drbd_peer_device *peer_device, bool res
 		} else
 			resync_done = is_sync_state(peer_device, NOW);
 	}
-
 	if (resync_done)
 		drbd_resync_finished(peer_device, D_MASK);
 
@@ -2242,8 +2241,10 @@ static void do_device_work(struct drbd_device *device, const unsigned long todo)
 
 static void do_peer_device_work(struct drbd_peer_device *peer_device, const unsigned long todo)
 {
+	if (test_bit(RS_PROGRESS, &todo))
+		drbd_broadcast_sync_progress(peer_device);
 	if (test_bit(RS_DONE, &todo) ||
-	    test_bit(RS_PROGRESS, &todo))
+	    test_bit(RS_LAZY_BM_WRITE, &todo))
 		update_on_disk_bitmap(peer_device, test_bit(RS_DONE, &todo));
 	if (test_bit(RS_START, &todo))
 		do_start_resync(peer_device);
@@ -2260,6 +2261,7 @@ static void do_peer_device_work(struct drbd_peer_device *peer_device, const unsi
 
 #define DRBD_PEER_DEVICE_WORK_MASK	\
 	((1UL << RS_START)		\
+	|(1UL << RS_LAZY_BM_WRITE)	\
 	|(1UL << RS_PROGRESS)		\
 	|(1UL << RS_DONE)		\
 	)
diff --git a/drbd/drbd_state.c b/drbd/drbd_state.c
index 90f380f63527..294cf1b9db07 100644
--- a/drbd/drbd_state.c
+++ b/drbd/drbd_state.c
@@ -2074,6 +2074,7 @@ static void initialize_resync(struct drbd_peer_device *peer_device)
 	peer_device->rs_last_sect_ev = 0;
 	peer_device->rs_total = tw;
 	peer_device->rs_start = now;
+	peer_device->rs_last_writeout = now;
 	for (i = 0; i < DRBD_SYNC_MARKS; i++) {
 		peer_device->rs_mark_left[i] = tw;
 		peer_device->rs_mark_time[i] = now;
@@ -2252,7 +2253,7 @@ static void finish_state_change(struct drbd_resource *resource, struct completio
 				peer_device->ov_last_oos_start = 0;
 				peer_device->ov_last_skipped_size = 0;
 				peer_device->ov_last_skipped_start = 0;
-
+				peer_device->rs_last_writeout = now;
 				for (i = 0; i < DRBD_SYNC_MARKS; i++) {
 					peer_device->rs_mark_left[i] = peer_device->ov_left;
 					peer_device->rs_mark_time[i] = now;
-- 
2.26.2

