[DRBD-cvs] svn commit by phil - r2453 - in trunk: drbd drbd/linux user - * Removed some explicit calls to drbd_thread_ ... funct

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Mon Sep 25 13:32:46 CEST 2006


Author: phil
Date: 2006-09-25 13:32:44 +0200 (Mon, 25 Sep 2006)
New Revision: 2453

Modified:
   trunk/drbd/drbd_actlog.c
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_nl.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_req.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd.h
   trunk/user/drbdsetup.c
Log:
* Removed some explicit calls to drbd_thread_ ... functions. 
  My goal is that all this thread start/stop happens out of the
  after_statche_ch() function.
  
* Removed the last drbd_thread_stop() from the after_state_ch()
  function. (Only non blocking calls remain)

* Introduced a new Connection State: "Disconnecting".

* drbd_nl_config_net() no longer implicitly disconnects.

* Removed the race between mdev->net_conf = XXX in
  drbd_disconnect() and drbd_nl_config_net()



Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/drbd/drbd_actlog.c	2006-09-25 11:32:44 UTC (rev 2453)
@@ -646,8 +646,7 @@
 				     (unsigned long)sector,
 				     ext->lce.lc_number, ext->rs_left, cleared);
 				// FIXME brrrgs. should never happen!
-				drbd_force_state(mdev,NS(conn,StandAlone));
-				drbd_thread_stop_nowait(&mdev->receiver);
+				drbd_force_state(mdev,NS(conn,Disconnecting));
 				return;
 			}
 		} else {

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/drbd/drbd_main.c	2006-09-25 11:32:44 UTC (rev 2453)
@@ -611,6 +611,9 @@
 	if( (ns.conn == StartingSyncT || ns.conn == StartingSyncS ) &&
 	    os.conn > Connected) rv=SS_ResyncRunning;
 
+	if( ns.conn == Disconnecting && os.conn == StandAlone) 
+		rv=SS_AlreadyStandAlone;
+
 	return rv;
 }
 
@@ -633,7 +636,7 @@
 
 	/* Dissalow Network errors to configure a device's network part */
 	if( (ns.conn >= BrokenPipe && ns.conn <= NetworkFailure ) && 
-	    os.conn == StandAlone ) {
+	    os.conn <= Disconnecting ) {
 		ns.conn = os.conn;
 	}
 
@@ -652,7 +655,7 @@
 		     ns.pdsk < Inconsistent ) ns.pdsk = DUnknown;
 	}
 
-	if( ns.conn == StandAlone && ns.disk == Diskless ) {
+	if( ns.conn <= Disconnecting && ns.disk == Diskless ) {
 		ns.pdsk = DUnknown;
 	}
 
@@ -779,7 +782,7 @@
 	}
 
 	if ( os.disk == Diskless && os.conn == StandAlone &&
-	     (ns.disk > Diskless || ns.conn > StandAlone) ) {
+	     (ns.disk > Diskless || ns.conn >= Unconnected) ) {
 		int i;
 		i = try_module_get(THIS_MODULE);
 		D_ASSERT(i);
@@ -995,17 +998,16 @@
 		lc_free(mdev->act_log); mdev->act_log = NULL;
 	}
 
-	if ( os.conn != StandAlone && ns.conn == StandAlone ) {
+	if ( os.conn != Disconnecting && ns.conn <= Disconnecting ) {
 		drbd_thread_stop_nowait(&mdev->receiver);
 	}
 
 	if ( os.conn != Unconnected && ns.conn == Unconnected ) {
-		drbd_thread_stop(&mdev->receiver);
-		drbd_thread_start(&mdev->receiver);
+		drbd_thread_restart_nowait(&mdev->receiver);
 	}
 
-	if ( os.disk == Diskless && os.conn == StandAlone &&
-	     (ns.disk > Diskless || ns.conn > StandAlone) ) {
+	if ( os.disk == Diskless && os.conn <= Disconnecting &&
+	     (ns.disk > Diskless || ns.conn >= Unconnected) ) {
 		if(!drbd_thread_start(&mdev->worker)) {
 			module_put(THIS_MODULE);
 		}
@@ -1034,7 +1036,11 @@
 	spin_unlock(&thi->t_lock);
 	complete(&thi->startstop); // notify: thi->task is set.
 
-	retval = thi->function(thi);
+	while(1) {
+		retval = thi->function(thi);
+		if(get_t_state(thi) != Restarting) break;
+		thi->t_state = Running;
+	}
 
 	spin_lock(&thi->t_lock);
 	thi->task = NULL;
@@ -1107,6 +1113,7 @@
 
 	if (thi->t_state == None) {
 		spin_unlock(&thi->t_lock);
+		if(restart) drbd_thread_start(thi);
 		return;
 	}
 
@@ -1116,12 +1123,6 @@
 			return;
 		}
 
-		if (ns == Restarting && thi->t_state == Exiting) {
-			// Already Exiting. Cannot restart!
-			spin_unlock(&thi->t_lock);
-			return;
-		}
-
 		thi->t_state = ns;
 		smp_mb();
 		if (thi->task != current) {

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/drbd/drbd_nl.c	2006-09-25 11:32:44 UTC (rev 2453)
@@ -934,8 +934,13 @@
 	struct crypto_tfm* tfm = NULL;
 	struct hlist_head *new_tl_hash = NULL;
 	struct hlist_head *new_ee_hash = NULL;
-	struct Drbd_Conf *odev;
+	drbd_dev *odev;
 
+	if (mdev->state.conn > StandAlone) {
+		retcode=HaveNetConfig;
+		goto fail;
+	}
+
 	new_conf = kmalloc(sizeof(struct net_conf),GFP_KERNEL);
 	if(!new_conf) {			
 		retcode=KMallocFailed;
@@ -976,21 +981,22 @@
 #define M_PORT(A) (((struct sockaddr_in *)&A->my_addr)->sin_port)
 #define O_ADDR(A) (((struct sockaddr_in *)&A->peer_addr)->sin_addr.s_addr)
 #define O_PORT(A) (((struct sockaddr_in *)&A->peer_addr)->sin_port)
+	retcode = NoError;
 	for(i=0;i<minor_count;i++) {
 		odev = minor_to_mdev(i);
-		if(!odev) continue;
-		if( mdev != odev && odev->state.conn > StandAlone &&
-		    M_ADDR(new_conf) == M_ADDR(odev->net_conf) &&
-		    M_PORT(new_conf) == M_PORT(odev->net_conf) ) {
-			retcode=LAAlreadyInUse;
-			goto fail;
+		if(!odev || odev == mdev) continue;
+		if( inc_net(odev)) {
+			if( M_ADDR(new_conf) == M_ADDR(odev->net_conf) &&
+			    M_PORT(new_conf) == M_PORT(odev->net_conf) ) {
+				retcode=LAAlreadyInUse;
+			}
+			if(O_ADDR(new_conf) == O_ADDR(odev->net_conf) &&
+			   O_PORT(new_conf) == O_PORT(odev->net_conf) ) {
+				retcode=OAAlreadyInUse;
+			}
+			dec_net(odev);
+			if(retcode != NoError) goto fail;
 		}
-		if( mdev != odev && odev->state.conn > StandAlone &&
-		    O_ADDR(new_conf) == O_ADDR(odev->net_conf) &&
-		    O_PORT(new_conf) == O_PORT(odev->net_conf) ) {
-			retcode=OAAlreadyInUse;
-			goto fail;
-		}
 	}
 #undef M_ADDR
 #undef M_PORT
@@ -1058,20 +1064,7 @@
 		new_conf->ping_int = new_conf->ping_int+1;
 #endif
 
-	drbd_sync_me(mdev);
-	drbd_thread_stop(&mdev->receiver); // conn = StadAlone afterwards
-	drbd_free_sock(mdev);
-
-	/* As soon as mdev->state.conn < Unconnected nobody can increase
-	   the net_cnt. Wait until the net_cnt is 0. */
-	if ( wait_event_interruptible( mdev->cstate_wait,
-				       atomic_read(&mdev->net_cnt) == 0 ) ) {
-		retcode=GotSignal;
-		goto fail;
-	}
-
-	/* Now we may touch net_conf */
-	if (mdev->net_conf) kfree(mdev->net_conf);
+	D_ASSERT(mdev->net_conf==NULL);
 	mdev->net_conf = new_conf;
 
 	mdev->send_cnt = 0;
@@ -1114,7 +1107,7 @@
 {
 	int retcode;
 
-	retcode = _drbd_request_state(mdev,NS(conn,StandAlone),0);	// silently.
+	retcode = _drbd_request_state(mdev,NS(conn,Disconnecting),0);	// silently.
 
 	if ( retcode == SS_NothingToDo ) goto done;
 	if ( retcode == SS_PrimaryNOP ) {
@@ -1124,7 +1117,7 @@
 			   mdev->state.conn < TearDown );
 		if( mdev->state.conn < TearDown ) goto done;
 
-		retcode = drbd_request_state(mdev,NS(conn,StandAlone));
+		retcode = drbd_request_state(mdev,NS(conn,Disconnecting));
 	}
 
 	if( retcode < SS_Success ) goto fail;

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/drbd/drbd_receiver.c	2006-09-25 11:32:44 UTC (rev 2453)
@@ -548,10 +548,7 @@
 
 	set_fs(oldfs);
 
-	if(rv != size) {
-		drbd_force_state(mdev,NS(conn,BrokenPipe));
-		drbd_thread_restart_nowait(&mdev->receiver);
-	}
+	if(rv != size) drbd_force_state(mdev,NS(conn,BrokenPipe));
 
 	return rv;
 }
@@ -631,7 +628,7 @@
 	if (err) {
 		ERR("Unable to bind sock2 (%d)\n", err);
 		sock_release(sock2);
-		drbd_force_state(mdev,NS(conn,StandAlone));
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return NULL;
 	}
 
@@ -677,7 +674,7 @@
 	struct socket *s, *sock,*msock;
 	int try,h;
 
-	D_ASSERT(mdev->state.conn > StandAlone);
+	D_ASSERT(mdev->state.conn >= Unconnected);
 	D_ASSERT(!mdev->data.socket);
 
 	if(drbd_request_state(mdev,NS(conn,WFConnection)) < SS_Success ) return 0;
@@ -736,7 +733,7 @@
 			}
 		}
 
-		if(mdev->state.conn == StandAlone) return -1;
+		if(mdev->state.conn <= Disconnecting) return -1;
 		if(signal_pending(current)) {
 			flush_signals(current);
 			smp_rmb();
@@ -1793,8 +1790,7 @@
 
 	if (hg == -1000) {
 		ALERT("Unrelated data, dropping connection!\n");
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return conn_mask;
 	}
 
@@ -1802,22 +1798,19 @@
 		ALERT("Split-Brain detected, dropping connection!\n");
 		drbd_uuid_dump(mdev,"self",mdev->bc->md.uuid);
 		drbd_uuid_dump(mdev,"peer",mdev->p_uuid);
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return conn_mask;
 	}
 
 	if (hg > 0 && mdev->state.disk <= Inconsistent ) {
 		ERR("I shall become SyncSource, but I am inconsistent!\n");
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return conn_mask;
 	}
 	if (hg < 0 && 
 	    mdev->state.role == Primary && mdev->state.disk != Negotiating ) {
 		ERR("I shall become SyncTarget, but I am primary!\n");
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return conn_mask;
 	}
 
@@ -1876,8 +1869,7 @@
 				'A'-1+mdev->net_conf->wire_protocol,
 				peer_proto);
 		}
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return FALSE;
 	}
 
@@ -1962,8 +1954,7 @@
 
 	if(p_size == 0 && mdev->state.disk == Diskless ) {
 		ERR("some backing storage is needed\n");
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return FALSE;
 	}
 
@@ -1994,8 +1985,7 @@
 		   mdev->state.disk >= Outdated ) {
 			dec_local(mdev);
 			ERR("The peer's disk size is too small!\n");
-			drbd_force_state(mdev,NS(conn,StandAlone));
-			drbd_thread_stop_nowait(&mdev->receiver);
+			drbd_force_state(mdev,NS(conn,Disconnecting));
 			mdev->bc->dc.disk_size = my_usize;
 			return FALSE;
 		}
@@ -2027,8 +2017,7 @@
 		if(nconn == conn_mask) return FALSE;
 
 		if(drbd_request_state(mdev,NS(conn,nconn)) < SS_Success) {
-			drbd_force_state(mdev,NS(conn,StandAlone));
-			drbd_thread_stop_nowait(&mdev->receiver);
+			drbd_force_state(mdev,NS(conn,Disconnecting));
 			return FALSE;
 		}
 	}
@@ -2186,8 +2175,7 @@
 	}
 
 	if(rv < SS_Success) {
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
+		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return FALSE;
 	}
 
@@ -2555,12 +2543,6 @@
 
 	INFO("Connection closed\n");
 
-	/* FIXME I'm not sure, there may still be a race? */
-	if(mdev->state.conn == StandAlone && mdev->net_conf ) {
-		kfree(mdev->net_conf);
-		mdev->net_conf = NULL;
-	}
-
 	drbd_md_sync(mdev);
 
 	if ( mdev->state.role == Primary ) {
@@ -2573,12 +2555,17 @@
 
 	spin_lock_irq(&mdev->req_lock);
 	if ( mdev->state.conn > Unconnected ) {
-		// Do not restart in case we are StandAlone
-		_drbd_set_state(mdev, _NS(conn,Unconnected), ScheduleAfter);
+		// Do not restart in case we are Disconnecting
+		_drbd_set_state(mdev, _NS(conn,Unconnected),0);
 	}
 	spin_unlock_irq(&mdev->req_lock);
 
-	drbd_md_sync(mdev);
+	if(mdev->state.conn == Disconnecting) {
+		wait_event( mdev->cstate_wait,atomic_read(&mdev->net_cnt) == 0 );
+		kfree(mdev->net_conf);
+		mdev->net_conf=NULL;
+		drbd_request_state(mdev, NS(conn,StandAlone));
+	}
 }
 
 /*
@@ -2843,7 +2830,7 @@
 		}
 		if( h < 0 ) {
 			WARN("Discarding network configuration.\n");
-			drbd_force_state(mdev,NS(conn,StandAlone));
+			drbd_force_state(mdev,NS(conn,Disconnecting));
 		}
 	} while ( h == 0 );
 

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/drbd/drbd_req.c	2006-09-25 11:32:44 UTC (rev 2453)
@@ -995,7 +995,7 @@
 		return 1;
 
 	// Unconfigured
-	if (mdev->state.conn == StandAlone &&
+	if (mdev->state.conn == Disconnecting &&
 	    mdev->state.disk == Diskless)
 		return 1;
 

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/drbd/drbd_strings.c	2006-09-25 11:32:44 UTC (rev 2453)
@@ -24,6 +24,7 @@
 
 static const char *drbd_conn_s_names[] = {
 	[StandAlone]     = "StandAlone",
+	[Disconnecting]  = "Disconnecting",
 	[Unconnected]    = "Unconnected",
 	[Timeout]        = "Timeout",
 	[BrokenPipe]     = "BrokenPipe",
@@ -70,6 +71,7 @@
 	[-SS_ConnectedOutdates] = "Refusing to be Outdated while Connected",
 	[-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated",
 	[-SS_ResyncRunning] = "Can not start resync since it is already active",
+	[-SS_AlreadyStandAlone] = "Can not disconnect a StandAlone device",
 	[-SS_CW_FailedByPeer] = "State changed was refused by peer node"
 };
 

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/drbd/linux/drbd.h	2006-09-25 11:32:44 UTC (rev 2453)
@@ -91,6 +91,7 @@
 	KMallocFailed,
 	DiscardNotAllowed,
 	HaveDiskConfig,
+	HaveNetConfig,
 	UnknownMandatoryTag,
 	MinorNotKnown,
 	StateNotAllowed,
@@ -130,7 +131,8 @@
  */
 typedef enum {
 	StandAlone,
-	Unconnected,
+	Disconnecting,  // Temporal state on the way to StandAlone.
+	Unconnected,    // >= Unconnected -> inc_net() succeeds
 	Timeout,
 	BrokenPipe,
 	NetworkFailure,
@@ -193,6 +195,7 @@
 	SS_ConnectedOutdates=-6,
 	SS_PrimaryNOP=-7,
 	SS_ResyncRunning=-8,
+	SS_AlreadyStandAlone=-9,
 	SS_CW_FailedByPeer=-10
 } set_st_err_t;
 

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-09-25 07:24:32 UTC (rev 2452)
+++ trunk/user/drbdsetup.c	2006-09-25 11:32:44 UTC (rev 2453)
@@ -356,6 +356,7 @@
 	EM(KMallocFailed) = "kmalloc() failed. Out of memory?",
 	EM(DiscardNotAllowed) = "--discard-my-data not allowed when primary.",
 	EM(HaveDiskConfig) = "HaveDiskConfig",
+	EM(HaveNetConfig) = "HaveNetConfig",
 	EM(UnknownMandatoryTag) = "UnknownMandatoryTag",
 	EM(MinorNotKnown) = "MinorNotKnown",
 	EM(StateNotAllowed) = "StateNotAllowed",
@@ -1096,7 +1097,7 @@
 	rv = cm->function(cm,minor,argc,argv);
 	if( rv ) return rv;
 	cm = find_cmd_by_name("disconnect");
-	rv |= cm->function(cm,minor,argc,argv);
+	cm->function(cm,minor,argc,argv);
 	cm = find_cmd_by_name("detach");
 	rv |= cm->function(cm,minor,argc,argv);
 



More information about the drbd-cvs mailing list