[DRBD-cvs] svn commit by phil - r2432 - trunk/drbd - When a thread was stopped with drbd_thread_stop_nowait(

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Tue Sep 19 18:04:15 CEST 2006


Author: phil
Date: 2006-09-19 18:04:14 +0200 (Tue, 19 Sep 2006)
New Revision: 2432

Modified:
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
Log:
When a thread was stopped with drbd_thread_stop_nowait() ( i.e.
not with the synchronous variant drbd_thread_stop() ).

Its t_state was left in "Exiting". This prevent it to got started
again by drbd_thread_start(), because there we test t_state
for beeing "None".

Fixed that.

PS: The symptoms of the bug were:
    insmod drbd.ko
    drbdadm up r0
    drbdadm down r0
    drbdadm up r0
    ps ax | grep drbd .... 
      no worker, an module count at 2!
 


Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-09-19 13:14:43 UTC (rev 2431)
+++ trunk/drbd/drbd_int.h	2006-09-19 16:04:14 UTC (rev 2432)
@@ -950,7 +950,7 @@
 extern void print_st_err(drbd_dev*, drbd_state_t, drbd_state_t, int );
 extern void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns,
 			   enum chg_state_flags);
-extern void drbd_thread_start(struct Drbd_thread *thi);
+extern int  drbd_thread_start(struct Drbd_thread *thi);
 extern void _drbd_thread_stop(struct Drbd_thread *thi, int restart, int wait);
 extern void drbd_free_resources(drbd_dev *mdev);
 extern void tl_release(drbd_dev *mdev,unsigned int barrier_nr,

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-09-19 13:14:43 UTC (rev 2431)
+++ trunk/drbd/drbd_main.c	2006-09-19 16:04:14 UTC (rev 2432)
@@ -993,7 +993,9 @@
 
 	if ( os.disk == Diskless && os.conn == StandAlone &&
 	     (ns.disk > Diskless || ns.conn > StandAlone) ) {
-		drbd_thread_start(&mdev->worker);
+		if(!drbd_thread_start(&mdev->worker)) {
+			module_put(THIS_MODULE);
+		}
 	}
 
 	/* it feels better to have the module_put last ... */
@@ -1022,8 +1024,8 @@
 	retval = thi->function(thi);
 
 	spin_lock(&thi->t_lock);
-	thi->task = 0;
-	thi->t_state = Exiting;
+	thi->task = NULL;
+	thi->t_state = None;
 	smp_mb();
 	spin_unlock(&thi->t_lock);
 
@@ -1045,7 +1047,7 @@
 	thi->mdev = mdev;
 }
 
-void drbd_thread_start(struct Drbd_thread *thi)
+int drbd_thread_start(struct Drbd_thread *thi)
 {
 	int pid;
 	drbd_dev *mdev = thi->mdev;
@@ -1067,7 +1069,7 @@
 		pid = kernel_thread(drbd_thread_setup, (void *) thi, CLONE_FS);
 		if (pid < 0) {
 			ERR("Couldn't start thread (%d)\n", pid);
-			return;
+			return FALSE;
 		}
 		wait_for_completion(&thi->startstop); // waits until thi->task is set
 		D_ASSERT(thi->task);
@@ -1075,6 +1077,8 @@
 	} else {
 		spin_unlock(&thi->t_lock);
 	}
+
+	return TRUE;
 }
 
 
@@ -1116,13 +1120,11 @@
 	spin_unlock(&thi->t_lock);
 
 	if (wait) {
-		if (thi->task == current) return;
-		D_ASSERT(thi->t_state == Exiting);
+		D_ASSERT(thi->task != current);
 		wait_for_completion(&thi->startstop);
 		spin_lock(&thi->t_lock);
-		thi->t_state = None;
-		smp_mb();
 		D_ASSERT(thi->task == NULL);
+		D_ASSERT(thi->t_state == None);
 		spin_unlock(&thi->t_lock);
 	}
 }
@@ -1989,7 +1991,6 @@
 	 */
 
 	drbd_thread_stop(&mdev->receiver);
-	drbd_thread_stop(&mdev->worker);
 
 	/* no need to lock it, I'm the only thread alive */
 	if ( mdev->epoch_size !=  0)



More information about the drbd-cvs mailing list