Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58ffa580 authored by Lars Ellenberg's avatar Lars Ellenberg Committed by Philipp Reisner
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.

Had to bump the protocol version differently, we are now 101.
Added verify_can_do_stop_sector() { protocol >= 97 && protocol != 100; }

Also, the return value convention for worker callbacks has changed,
we returned "true/false" for "keep the connection up" in 8.3,
we return 0 for success and <= for failure in 8.4.
Affected: receive_state()

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 970fbde1
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -971,6 +971,7 @@ struct drbd_conf {

	/* where does the admin want us to start? (sector) */
	sector_t ov_start_sector;
	sector_t ov_stop_sector;
	/* where are we now? (sector) */
	sector_t ov_position;
	/* Start sector of out of sync range (to merge printk reporting). */
@@ -2264,6 +2265,12 @@ static inline void dec_ap_bio(struct drbd_conf *mdev)
		wake_up(&mdev->misc_wait);
}

static inline bool verify_can_do_stop_sector(struct drbd_conf *mdev)
{
	return mdev->tconn->agreed_pro_version >= 97 &&
		mdev->tconn->agreed_pro_version != 100;
}

static inline int drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val)
{
	int changed = mdev->ed_uuid != val;
+9 −5
Original line number Diff line number Diff line
@@ -2939,6 +2939,7 @@ int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info)
{
	struct drbd_conf *mdev;
	enum drbd_ret_code retcode;
	struct start_ov_parms parms;

	retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_MINOR);
	if (!adm_ctx.reply_skb)
@@ -2947,19 +2948,22 @@ int drbd_adm_start_ov(struct sk_buff *skb, struct genl_info *info)
		goto out;

	mdev = adm_ctx.mdev;
	if (info->attrs[DRBD_NLA_START_OV_PARMS]) {

	/* resume from last known position, if possible */
		struct start_ov_parms parms =
			{ .ov_start_sector = mdev->ov_start_sector };
	parms.ov_start_sector = mdev->ov_start_sector;
	parms.ov_stop_sector = ULLONG_MAX;
	if (info->attrs[DRBD_NLA_START_OV_PARMS]) {
		int err = start_ov_parms_from_attrs(&parms, info);
		if (err) {
			retcode = ERR_MANDATORY_TAG;
			drbd_msg_put_info(from_attrs_err_to_txt(err));
			goto out;
		}
		/* w_make_ov_request expects position to be aligned */
		mdev->ov_start_sector = parms.ov_start_sector & ~BM_SECT_PER_BIT;
	}
	/* w_make_ov_request expects position to be aligned */
	mdev->ov_start_sector = parms.ov_start_sector & ~(BM_SECT_PER_BIT-1);
	mdev->ov_stop_sector = parms.ov_stop_sector;

	/* If there is still bitmap IO pending, e.g. previous resync or verify
	 * just being finished, wait for it before requesting a new resync. */
	drbd_suspend_io(mdev);
+9 −3
Original line number 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. */
		unsigned long bm_bits = drbd_bm_bits(mdev);
		unsigned long bit_pos;
		unsigned long long stop_sector = 0;
		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;
		else
			if (verify_can_do_stop_sector(mdev))
				stop_sector = mdev->ov_stop_sector;
		} else
			bit_pos = mdev->bm_resync_fo;
		/* Total sectors may be slightly off for oddly
		 * sized devices. So what. */
		seq_printf(seq,
			"\t%3d%% sector pos: %llu/%llu\n",
			"\t%3d%% sector pos: %llu/%llu",
			(int)(bit_pos / (bm_bits/100+1)),
			(unsigned long long)bit_pos * 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");
	}
}

+9 −1
Original line number Diff line number Diff line
@@ -3843,7 +3843,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
	 * already decided to close the connection again,
	 * we must not "re-establish" it here. */
	if (os.conn <= C_TEAR_DOWN)
		return false;
		return -ECONNRESET;

	/* If this is the "end of sync" confirmation, usually the peer disk
	 * transitions from D_INCONSISTENT to D_UP_TO_DATE. For empty (0 bits
@@ -3875,6 +3875,14 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi)
		}
	}

	/* 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_out_of_sync_print(mdev);
		drbd_resync_finished(mdev);
		return 0;
	}

	/* 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,
	 * but we think we are already done with the sync.
+13 −4
Original line number Diff line number Diff line
@@ -975,11 +975,13 @@ __drbd_set_state(struct drbd_conf *mdev, union drbd_state ns,
	wake_up(&mdev->state_wait);
	wake_up(&mdev->tconn->ping_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) &&
	    ns.conn < C_CONNECTED) {
	    ns.conn <= C_CONNECTED) {
		mdev->ov_start_sector =
			BM_BIT_TO_SECT(drbd_bm_bits(mdev) - mdev->ov_left);
		if (mdev->ov_left)
			dev_info(DEV, "Online Verify reached sector %llu\n",
				(unsigned long long)mdev->ov_start_sector);
	}
@@ -1422,6 +1424,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)
		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
	&& verify_can_do_stop_sector(mdev))
		drbd_send_state(mdev, ns);

	/* 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 (test_and_clear_bit(STATE_SENT, &mdev->tconn->flags))
Loading