[DRBD-cvs] DRBD CVS: drbd by phil from

drbd-cvs@linbit.com drbd-cvs@linbit.com
Mon, 12 Jan 2004 11:46:43 +0100 (CET)


DRBD CVS committal

Author  : phil
Host    : 
Module  : drbd

Dir     : drbd/drbd


Modified Files:
      Tag: rel-0_7-branch
	drbd_actlog.c drbd_dsender.c drbd_int.h 


Log Message:
Some work on drbd_wait_for_other_sync_groups() ... Next step is to test
this...

===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_actlog.c,v
retrieving revision 1.1.2.44
retrieving revision 1.1.2.45
diff -u -3 -r1.1.2.44 -r1.1.2.45
--- drbd_actlog.c	12 Jan 2004 09:31:36 -0000	1.1.2.44
+++ drbd_actlog.c	12 Jan 2004 10:46:42 -0000	1.1.2.45
@@ -514,8 +514,8 @@
 			D_ASSERT((long)ext->rs_left >= 0);
 		} else {
 			WARN("Recounting sectors (resync LRU too small?)\n");
-			lc_changed(mdev->resync,(struct lc_element*)ext);
 			ext->rs_left = bm_count_sectors(mdev->mbds_id,enr);
+			lc_changed(mdev->resync,(struct lc_element*)ext);
 		}
 		lc_put(mdev->resync,(struct lc_element*)ext);
 	} else {
@@ -589,8 +589,8 @@
 	bm_ext = (struct bm_extent*) lc_get(mdev->resync,enr);
 	if (bm_ext) {
 		if(bm_ext->lce.lc_number != enr) {
-			lc_changed(mdev->resync,(struct lc_element*)bm_ext);
 			bm_ext->rs_left = bm_count_sectors(mdev->mbds_id,enr);
+			lc_changed(mdev->resync,(struct lc_element*)bm_ext);
 			wake_up(&mdev->al_wait);
 		}
 		set_bit(BME_NO_WRITES,&bm_ext->flags); // within the lock
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_dsender.c,v
retrieving revision 1.1.2.40
retrieving revision 1.1.2.41
diff -u -3 -r1.1.2.40 -r1.1.2.41
--- drbd_dsender.c	11 Jan 2004 08:56:40 -0000	1.1.2.40
+++ drbd_dsender.c	12 Jan 2004 10:46:42 -0000	1.1.2.41
@@ -98,57 +98,86 @@
 	return ok;
 }
 
+STATIC drbd_dev *ds_find_osg(drbd_dev *mdev)
+{
+	drbd_dev *odev;
+	int i;
+
+	for (i=0; i < minor_count; i++) {
+		odev = drbd_conf + i;
+		if ( odev->sync_conf.group < mdev->sync_conf.group
+		     && odev->cstate > Connected ) {
+			return odev;
+		}
+	}
+
+	return 0;
+}
+
 STATIC void _ds_wait_osg(drbd_dev* odev, struct drbd_hook* dh)
 {
 	// This is a callback, I better not assume that this 
 	// is a context which allows to send something from.
-
+	unsigned long flags;
 	drbd_dev *mdev = (drbd_dev*) dh->data;
+	int added=0;
 
 	if(odev->cstate <= Connected) {
-		set_bit(SYNC_CONTINUE,&mdev->flags);
-		wake_up_interruptible(&mdev->dsender_wait);
-		list_del(&dh->list); // TODO: Lock for list manipulaton.
-		kfree(dh);
+		spin_lock_irqsave(&mdev->req_lock,flags);
+		list_del(&dh->list);
+		spin_unlock_irqrestore(&mdev->req_lock,flags);
+	retry:
+		if( (odev = ds_find_osg(mdev)) ) {
+			spin_lock_irqsave(&odev->req_lock,flags);
+			if(odev->cstate > Connected) {
+				list_add(&dh->list,&odev->cstate_hook);
+				added=1;
+			}
+			spin_unlock_irqrestore(&odev->req_lock,flags);
+			if(!added) goto retry;
+		} else {
+			set_bit(SYNC_CONTINUE,&mdev->flags);
+			wake_up_interruptible(&mdev->dsender_wait);
+			kfree(dh);
+		}
 	}
 }
 
-STATIC void drbd_wait_for_other_sync_groups(struct Drbd_Conf *mdev)
+STATIC int drbd_wait_for_other_sync_groups(drbd_dev *mdev)
 {
 	drbd_dev *odev;
 	struct drbd_hook *dh=NULL;
-	int i;
+	int added=0;
 
  retry:
-	for (i=0; i < minor_count; i++) {
-		odev = drbd_conf + i;
-		if (signal_pending(current)) return;
-		if ( odev->sync_conf.group < mdev->sync_conf.group
-		     && odev->cstate > Connected ) {
-			INFO("Syncer waits for sync group %i\n",
-			     odev->sync_conf.group);
-			drbd_send_short_cmd(mdev,SyncStop);
-			set_cstate(mdev,PausedSyncT);
-
-			dh=kmalloc(sizeof(struct drbd_hook),GFP_KERNEL);
-			if(!dh) {
-				ERR("could not kmalloc drbd_hook\n");
-				current->state = TASK_INTERRUPTIBLE;
-				schedule_timeout(HZ);
-				goto retry;
-			}
+	odev = ds_find_osg(mdev);
+	if(!odev) return FALSE;
 
-			dh->data = mdev;
-			dh->callback = _ds_wait_osg;
+	while( dh == NULL ) {
+		dh=kmalloc(sizeof(struct drbd_hook),GFP_KERNEL);
+		if(dh) break;
+		ERR("could not kmalloc drbd_hook\n");
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(HZ);
+	}
 
-			list_add(&dh->list,&odev->cstate_hook);
-			// TODO: Need some locking here!
-			// over the test of odev->cstate and list_add.
-			// otherwise we could miss the run of the hook!
+	dh->data = mdev;
+	dh->callback = _ds_wait_osg;
 
-			return;
-		}
+	spin_lock_irq(&odev->req_lock);
+	if(odev->cstate > Connected) {
+		list_add(&dh->list,&odev->cstate_hook);
+		added=1;
 	}
+	spin_unlock_irq(&odev->req_lock);
+	if(!added) goto retry;
+
+	INFO("Syncer waits for sync group %i\n",
+	     odev->sync_conf.group);
+	drbd_send_short_cmd(mdev,SyncStop);
+	set_cstate(mdev,PausedSyncT);
+
+	return TRUE;
 }
 
 /* bool */
@@ -169,7 +198,7 @@
 	}
 	// /Remove later
 
-	drbd_wait_for_other_sync_groups(mdev);
+	if(drbd_wait_for_other_sync_groups(mdev)) return FALSE;
 
 	for(i=0;i<number;i++) {
 		struct Pending_read *pr;
@@ -282,7 +311,8 @@
 			D_ASSERT(list_empty(&mdev->resync->lru));
 		}
 
-		if(test_and_clear_bit(SYNC_CONTINUE,&mdev->flags)) {
+		if(test_and_clear_bit(SYNC_CONTINUE,&mdev->flags) && 
+		   (mdev->cstate == PausedSyncT) ) {
 			time=SLEEP_TIME;
 			INFO("resumed synchronisation.\n");
 			drbd_send_short_cmd(mdev,SyncCont);
@@ -290,8 +320,7 @@
 		}
 
 		if(time == SLEEP_TIME) {
-			if(!ds_issue_requests(mdev) || 
-			   mdev->cstate == PausedSyncT ) {
+			if (!ds_issue_requests(mdev)) {
 				time=MAX_SCHEDULE_TIMEOUT;
 			}
 			if (!disable_io_hints) {
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_int.h,v
retrieving revision 1.58.2.82
retrieving revision 1.58.2.83
diff -u -3 -r1.58.2.82 -r1.58.2.83
--- drbd_int.h	12 Jan 2004 09:31:36 -0000	1.58.2.82
+++ drbd_int.h	12 Jan 2004 10:46:42 -0000	1.58.2.83
@@ -921,15 +921,21 @@
 {
 	struct list_head *le;
 	struct drbd_hook *dh;
+	unsigned long flags;
 
+	spin_lock_irqsave(&mdev->req_lock,flags);
 	mdev->cstate = cs;
-	wake_up_interruptible(&mdev->cstate_wait);
 
 	while(!list_empty(&mdev->cstate_hook)) {
 		le = mdev->cstate_hook.next;
 		dh = list_entry(le, struct drbd_hook,list);
+		spin_unlock_irqrestore(&mdev->req_lock,flags);
 		dh->callback(mdev,dh);
+		spin_lock_irqsave(&mdev->req_lock,flags);
 	}
+	spin_unlock_irqrestore(&mdev->req_lock,flags);
+
+	wake_up_interruptible(&mdev->cstate_wait);
 }
 
 static inline void inc_pending(drbd_dev* mdev)