[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);
}