[DRBD-cvs] r1443 - trunk/drbd

drbd-user@lists.linbit.com drbd-user@lists.linbit.com
Tue, 20 Jul 2004 09:40:08 +0200 (CEST)


Author: lars
Date: 2004-07-20 09:40:08 +0200 (Tue, 20 Jul 2004)
New Revision: 1443

Modified:
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_worker.c
Log:
make sure we call w_resume_next_sg on drbd_disconnect

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2004-07-18 21:47:00 UTC (rev 1442)
+++ trunk/drbd/drbd_receiver.c	2004-07-20 07:40:08 UTC (rev 1443)
@@ -1736,6 +1736,31 @@
 {
 	D_ASSERT(mdev->cstate < Connected);
 	mdev->o_state = Unknown;
+
+	/* in case we have been syncing, and then we drop the connection,
+	 * we need to "w_resume_next_sg", which we try to achieve by
+	 * setting the STOP_SYNC_TIMER bit, and schedulung the timer for
+	 * immediate execution.
+	 * unfortunately we cannot be sure that the timer already triggered.
+	 *
+	 * so we del_timer_sync here, and check that bit.
+	 * if it is still set, we queue w_resume_next_sg anyways,
+	 * just to be sure.
+	 */
+
+	del_timer_sync(&mdev->resync_timer);
+	spin_lock_irq(&mdev->req_lock);
+	if (test_and_clear_bit(STOP_SYNC_TIMER,&mdev->flags)) {
+		mdev->resync_work.cb = w_resume_next_sg;
+		if (list_empty(&mdev->resync_work.list))
+			_drbd_queue_work(&mdev->data.work,&mdev->resync_work);
+		// else: already queued, we only need to release the lock.
+	} else {
+		D_ASSERT(mdev->resync_work.cb == w_resync_inactive);
+	}
+	spin_unlock_irq(&mdev->req_lock);
+
+
 	drbd_thread_stop_nowait(&mdev->worker);
 	drbd_thread_stop(&mdev->asender);
 

Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c	2004-07-18 21:47:00 UTC (rev 1442)
+++ trunk/drbd/drbd_worker.c	2004-07-20 07:40:08 UTC (rev 1443)
@@ -454,6 +454,8 @@
 	PARANOIA_BUG_ON(w != &mdev->resync_work);
 
 	if(unlikely(cancel)) return 1;
+	/* FIXME THINK what about w_resume_next_sg ?? */
+
 	if(unlikely(mdev->cstate < Connected)) {
 		ERR("Confused in w_make_resync_request()! cstate < Connected");
 		return 0;
@@ -510,6 +512,12 @@
 	}
 
 	if(drbd_bm_rs_done(mdev)) {
+		/* last syncer _request_ was sent,
+		 * but the RSDataReply not yet received.  sync will end (and
+		 * next sync group will resume), as soon as we receive the last
+		 * resync data block, and the last bit is cleared.
+		 * until then resync "work" is "inactive" ...
+		 */
 		mdev->resync_work.cb = w_resync_inactive;
 		return 1;
 	}
@@ -546,7 +554,10 @@
 	D_ASSERT(drbd_bm_total_weight(mdev) == 0);
 	mdev->rs_total = 0;
 
-	set_cstate(mdev,Connected); // w_resume_next_sg() gets called here.
+	set_cstate(mdev,Connected);
+	/* FIXME
+	 * _queueing_ of w_resume_next_sg() gets _scheduled_ here.
+	 * maybe rather _do_ it right here instead? */
 	return 1;
 }
 
@@ -863,8 +874,16 @@
 	     (unsigned long) mdev->rs_total);
 
 	// FIXME: this was a PARANOIA_BUG_ON, but it triggered! ??
-	ERR_IF(mdev->resync_work.cb != w_resync_inactive)
+	if (mdev->resync_work.cb != w_resync_inactive) {
+		if (mdev->resync_work.cb == w_make_resync_request)
+			ERR("resync_work.cb == w_make_resync_request, should be w_resync_inactive\n");
+		else if (mdev->resync_work.cb == w_resume_next_sg)
+			ERR("resync_work.cb == w_resume_next_sg, should be w_resync_inactive\n");
+		else
+			ERR("resync_work.cb == %p ???, should be w_resync_inactive\n",
+					mdev->resync_work.cb);
 		return;
+	}
 
 	if ( mdev->rs_total == 0 ) {
 		drbd_resync_finished(mdev);
@@ -874,7 +893,6 @@
 	/* FIXME THINK
 	 * use mdev->cstate (we may already be paused...) or side here ?? */
 	if (mdev->cstate == SyncTarget) {
-		drbd_bm_reset_find(mdev);
 		D_ASSERT(!test_bit(STOP_SYNC_TIMER,&mdev->flags));
 		mod_timer(&mdev->resync_timer,jiffies);
 	}