Commit 02b91b55 authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Jens Axboe
Browse files

drbd: introduce stop-sector to online verify



We now can schedule only a specific range of sectors for online verify,
or interrupt a running verify without interrupting the connection.

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 9f2247bb
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -1052,6 +1052,7 @@ struct drbd_conf {


	/* where does the admin want us to start? (sector) */
	/* where does the admin want us to start? (sector) */
	sector_t ov_start_sector;
	sector_t ov_start_sector;
	sector_t ov_stop_sector;
	/* where are we now? (sector) */
	/* where are we now? (sector) */
	sector_t ov_position;
	sector_t ov_position;
	/* Start sector of out of sync range (to merge printk reporting). */
	/* Start sector of out of sync range (to merge printk reporting). */
+13 −4
Original line number Original line Diff line number Diff line
@@ -1231,11 +1231,13 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
	wake_up(&mdev->misc_wait);
	wake_up(&mdev->misc_wait);
	wake_up(&mdev->state_wait);
	wake_up(&mdev->state_wait);


	/* aborted verify run. log the last position */
	/* Aborted verify run, or we reached the stop sector.
	 * Log the last position, unless end-of-device. */
	if ((os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) &&
	if ((os.conn == C_VERIFY_S || os.conn == C_VERIFY_T) &&
	    ns.conn < C_CONNECTED) {
	    ns.conn <= C_CONNECTED) {
		mdev->ov_start_sector =
		mdev->ov_start_sector =
			BM_BIT_TO_SECT(drbd_bm_bits(mdev) - mdev->ov_left);
			BM_BIT_TO_SECT(drbd_bm_bits(mdev) - mdev->ov_left);
		if (mdev->ov_left)
			dev_info(DEV, "Online Verify reached sector %llu\n",
			dev_info(DEV, "Online Verify reached sector %llu\n",
				(unsigned long long)mdev->ov_start_sector);
				(unsigned long long)mdev->ov_start_sector);
	}
	}
@@ -1703,6 +1705,13 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
	if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED)
	if (os.disk < D_UP_TO_DATE && os.conn >= C_SYNC_SOURCE && ns.conn == C_CONNECTED)
		drbd_send_state(mdev, ns);
		drbd_send_state(mdev, ns);


	/* Verify finished, or reached stop sector.  Peer did not know about
	 * the stop sector, and we may even have changed the stop sector during
	 * verify to interrupt/stop early.  Send the new state. */
	if (os.conn == C_VERIFY_S && ns.conn == C_CONNECTED
	&& mdev->agreed_pro_version >= 97)
		drbd_send_state(mdev, ns);

	/* Wake up role changes, that were delayed because of connection establishing */
	/* Wake up role changes, that were delayed because of connection establishing */
	if (os.conn == C_WF_REPORT_PARAMS && ns.conn != C_WF_REPORT_PARAMS) {
	if (os.conn == C_WF_REPORT_PARAMS && ns.conn != C_WF_REPORT_PARAMS) {
		clear_bit(STATE_SENT, &mdev->flags);
		clear_bit(STATE_SENT, &mdev->flags);
+7 −4
Original line number Original line Diff line number Diff line
@@ -2211,8 +2211,10 @@ static int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
				    struct drbd_nl_cfg_reply *reply)
				    struct drbd_nl_cfg_reply *reply)
{
{
	/* default to resume from last known position, if possible */
	/* default to resume from last known position, if possible */
	struct start_ov args =
	struct start_ov args = {
		{ .start_sector = mdev->ov_start_sector };
		.start_sector = mdev->ov_start_sector,
		.stop_sector = ULLONG_MAX,
	};


	if (!start_ov_from_tags(mdev, nlp->tag_list, &args)) {
	if (!start_ov_from_tags(mdev, nlp->tag_list, &args)) {
		reply->ret_code = ERR_MANDATORY_TAG;
		reply->ret_code = ERR_MANDATORY_TAG;
@@ -2224,8 +2226,9 @@ static int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
	drbd_suspend_io(mdev);
	drbd_suspend_io(mdev);
	wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));
	wait_event(mdev->misc_wait, !test_bit(BITMAP_IO, &mdev->flags));


	/* w_make_ov_request expects position to be aligned */
	/* w_make_ov_request expects start position to be aligned */
	mdev->ov_start_sector = args.start_sector & ~BM_SECT_PER_BIT;
	mdev->ov_start_sector = args.start_sector & ~(BM_SECT_PER_BIT-1);
	mdev->ov_stop_sector = args.stop_sector;
	reply->ret_code = drbd_request_state(mdev,NS(conn,C_VERIFY_S));
	reply->ret_code = drbd_request_state(mdev,NS(conn,C_VERIFY_S));
	drbd_resume_io(mdev);
	drbd_resume_io(mdev);
	return 0;
	return 0;
+9 −3
Original line number Original line Diff line number Diff line
@@ -167,18 +167,24 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
		 * we convert to sectors in the display below. */
		 * we convert to sectors in the display below. */
		unsigned long bm_bits = drbd_bm_bits(mdev);
		unsigned long bm_bits = drbd_bm_bits(mdev);
		unsigned long bit_pos;
		unsigned long bit_pos;
		unsigned long long stop_sector = 0;
		if (mdev->state.conn == C_VERIFY_S ||
		if (mdev->state.conn == C_VERIFY_S ||
		    mdev->state.conn == C_VERIFY_T)
		    mdev->state.conn == C_VERIFY_T) {
			bit_pos = bm_bits - mdev->ov_left;
			bit_pos = bm_bits - mdev->ov_left;
		else
			if (mdev->agreed_pro_version >= 97)
				stop_sector = mdev->ov_stop_sector;
		} else
			bit_pos = mdev->bm_resync_fo;
			bit_pos = mdev->bm_resync_fo;
		/* Total sectors may be slightly off for oddly
		/* Total sectors may be slightly off for oddly
		 * sized devices. So what. */
		 * sized devices. So what. */
		seq_printf(seq,
		seq_printf(seq,
			"\t%3d%% sector pos: %llu/%llu\n",
			"\t%3d%% sector pos: %llu/%llu",
			(int)(bit_pos / (bm_bits/100+1)),
			(int)(bit_pos / (bm_bits/100+1)),
			(unsigned long long)bit_pos * BM_SECT_PER_BIT,
			(unsigned long long)bit_pos * BM_SECT_PER_BIT,
			(unsigned long long)bm_bits * BM_SECT_PER_BIT);
			(unsigned long long)bm_bits * BM_SECT_PER_BIT);
		if (stop_sector != 0 && stop_sector != ULLONG_MAX)
			seq_printf(seq, " stop sector: %llu", stop_sector);
		seq_printf(seq, "\n");
	}
	}
}
}


+8 −0
Original line number Original line Diff line number Diff line
@@ -3255,6 +3255,14 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned
		}
		}
	}
	}


	/* explicit verify finished notification, stop sector reached. */
	if (os.conn == C_VERIFY_T && os.disk == D_UP_TO_DATE &&
	    peer_state.conn == C_CONNECTED && real_peer_disk == D_UP_TO_DATE) {
		ov_oos_print(mdev);
		drbd_resync_finished(mdev);
		return true;
	}

	/* peer says his disk is inconsistent, while we think it is uptodate,
	/* peer says his disk is inconsistent, while we think it is uptodate,
	 * and this happens while the peer still thinks we have a sync going on,
	 * and this happens while the peer still thinks we have a sync going on,
	 * but we think we are already done with the sync.
	 * but we think we are already done with the sync.
Loading