[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