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

drbd-cvs@linbit.com drbd-cvs@linbit.com
Sun, 11 Jan 2004 09:56:41 +0100 (CET)


DRBD CVS committal

Author  : phil
Host    : 
Module  : drbd

Dir     : drbd/drbd


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


Log Message:
Changed the way drbd_wait_for_other_sync_groups() works, so that 
dsender stays operational while waiting for an other sync group.

Completely untested. Probabely breaks something. Will test and
debug it later today.

===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_dsender.c,v
retrieving revision 1.1.2.39
retrieving revision 1.1.2.40
diff -u -3 -r1.1.2.39 -r1.1.2.40
--- drbd_dsender.c	10 Jan 2004 21:39:56 -0000	1.1.2.39
+++ drbd_dsender.c	11 Jan 2004 08:56:40 -0000	1.1.2.40
@@ -98,37 +98,56 @@
 	return ok;
 }
 
-void drbd_wait_for_other_sync_groups(struct Drbd_Conf *mdev)
+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.
+
+	drbd_dev *mdev = (drbd_dev*) dh->data;
+
+	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);
+	}
+}
+
+STATIC void drbd_wait_for_other_sync_groups(struct Drbd_Conf *mdev)
+{
+	drbd_dev *odev;
+	struct drbd_hook *dh=NULL;
 	int i;
-	int did_wait=0;
-	do {
-		for (i=0; i < minor_count; i++) {
-			if (signal_pending(current)) return;
-			if ( drbd_conf[i].sync_conf.group < mdev->sync_conf.group
-			  && drbd_conf[i].cstate > Connected )
-			{
-				int ret;
-				INFO("Syncer waits for sync group %i\n",
-				     drbd_conf[i].sync_conf.group);
-				drbd_send_short_cmd(mdev,SyncStop);
-				set_cstate(mdev,PausedSyncT);
-				ret = wait_event_interruptible(
-					drbd_conf[i].cstate_wait,
-					drbd_conf[i].cstate <= Connected );
-				// FIXME if (ret < 0) do something sensible...
-				did_wait=1;
-				// XXX why sleep again?
+
+ 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/10);
-				break;
-			};
+				schedule_timeout(HZ);
+				goto retry;
+			}
+
+			dh->data = mdev;
+			dh->callback = _ds_wait_osg;
+
+			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!
+
+			return;
 		}
-	} while (i < minor_count);
-	if (did_wait) {
-		INFO("resumed synchronisation.\n");
-		drbd_send_short_cmd(mdev,SyncCont);
-		set_cstate(mdev,SyncTarget);
 	}
 }
 
@@ -138,7 +157,7 @@
 	int number,i;
 	sector_t sector;
 
-#define SLEEP_TIME 10
+#define SLEEP_TIME (HZ/10)
 
 	number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ);
 
@@ -212,8 +231,9 @@
 static inline int _dsender_cond(struct Drbd_Conf *mdev)
 {
 	int rv;
-	rv = test_bit(START_SYNC,&mdev->flags)
-		|| test_bit(SYNC_FINISHED,&mdev->flags);
+	rv = test_bit(START_SYNC,&mdev->flags) // TODO Use Lars' style _FLAG 
+		|| test_bit(SYNC_FINISHED,&mdev->flags)
+		|| test_bit(SYNC_CONTINUE,&mdev->flags);
 
 	spin_lock_irq(&mdev->ee_lock);
 	rv |= !list_empty(&mdev->rdone_ee);
@@ -262,8 +282,16 @@
 			D_ASSERT(list_empty(&mdev->resync->lru));
 		}
 
+		if(test_and_clear_bit(SYNC_CONTINUE,&mdev->flags)) {
+			time=SLEEP_TIME;
+			INFO("resumed synchronisation.\n");
+			drbd_send_short_cmd(mdev,SyncCont);
+			set_cstate(mdev,SyncTarget);
+		}
+
 		if(time == SLEEP_TIME) {
-			if(!ds_issue_requests(mdev)) {
+			if(!ds_issue_requests(mdev) || 
+			   mdev->cstate == PausedSyncT ) {
 				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.80
retrieving revision 1.58.2.81
diff -u -3 -r1.58.2.80 -r1.58.2.81
--- drbd_int.h	10 Jan 2004 07:53:55 -0000	1.58.2.80
+++ drbd_int.h	11 Jan 2004 08:56:40 -0000	1.58.2.81
@@ -506,6 +506,7 @@
 #define PARTNER_DISKLESS   7
 #define SYNC_FINISHED      8
 #define PROCESS_EE_RUNNING 9
+#define SYNC_CONTINUE     10
 
 struct BitMap {
 	unsigned long dev_size;
@@ -528,8 +529,12 @@
 #define BME_NO_WRITES    0
 #define BME_LOCKED       1
 
-struct al_transaction;
-struct drbd_extent;
+struct drbd_hook {
+	struct list_head list;
+	void* data;
+	void (*callback) (drbd_dev*, struct drbd_hook* );
+};
+
 
 // TODO sort members for performance
 // MAYBE group them further
@@ -557,7 +562,8 @@
 	Drbd_State state;
 	Drbd_CState cstate;
 	wait_queue_head_t cstate_wait;
-	wait_queue_head_t state_wait;
+	struct list_head  cstate_hook; // processed if cstate changes.
+	wait_queue_head_t state_wait;  // TODO: Remove state_wait.
 	Drbd_State o_state;
 	unsigned long int la_size; // last agreed disk size
 	unsigned int send_cnt;
@@ -915,8 +921,17 @@
 
 static inline void set_cstate(drbd_dev* mdev,Drbd_CState cs)
 {
+	struct list_head *le;
+	struct drbd_hook *dh;
+
 	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);
+		dh->callback(mdev,dh);
+	}
 }
 
 static inline void inc_pending(drbd_dev* mdev)
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_main.c,v
retrieving revision 1.73.2.88
retrieving revision 1.73.2.89
diff -u -3 -r1.73.2.88 -r1.73.2.89
--- drbd_main.c	10 Jan 2004 19:24:00 -0000	1.73.2.88
+++ drbd_main.c	11 Jan 2004 08:56:40 -0000	1.73.2.89
@@ -996,6 +996,7 @@
 	mdev->pr_lock        = SPIN_LOCK_UNLOCKED;
 	mdev->send_task_lock = SPIN_LOCK_UNLOCKED;
 
+	INIT_LIST_HEAD(&mdev->cstate_hook);
 	INIT_LIST_HEAD(&mdev->free_ee);
 	INIT_LIST_HEAD(&mdev->active_ee);
 	INIT_LIST_HEAD(&mdev->sync_ee);