[DRBD-cvs] svn commit by phil - r2206 - in trunk/drbd: . linux - Improved a few details: *) Made sure a state request fa

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Mon May 22 20:58:47 CEST 2006


Author: phil
Date: 2006-05-22 20:58:45 +0200 (Mon, 22 May 2006)
New Revision: 2206

Modified:
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd.h
Log:
Improved a few details:
 *) Made sure a state request fails if it is even local not desirable.
 *) Made sure it failes if it becomes impossible during waiting for
    the peers answer.


Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-05-22 15:10:53 UTC (rev 2205)
+++ trunk/drbd/drbd_main.c	2006-05-22 18:58:45 UTC (rev 2206)
@@ -530,7 +530,7 @@
 /** 
  * cl_wide_st_chg:
  * Returns TRUE if this state change should be preformed as a cluster wide
- * transaction. 
+ * transaction. Of courese it returns 0 as soon as the connection is lost.
  */ 
 STATIC int cl_wide_st_chg(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns)
 {
@@ -567,24 +567,41 @@
 	drbd_change_state(mdev,ChgStateHard,mask,val);
 }
 
-static inline enum { REQS_SUCCESS=1, REQS_FAIL=2, REQS_NO_NEED=3 } 
-_req_st_cond(drbd_dev* mdev,drbd_state_t mask, drbd_state_t val)
+STATIC int pre_state_checks(drbd_dev* mdev, drbd_state_t ns);
+STATIC int drbd_send_state_req(drbd_dev *, drbd_state_t, drbd_state_t);
+
+set_st_err_t _req_st_cond(drbd_dev* mdev,drbd_state_t mask, drbd_state_t val)
 {
 	drbd_state_t os,ns;
+	unsigned long flags;
+	int rv;
 
-	if(test_and_clear_bit(CL_ST_CHG_SUCCESS,&mdev->flags)) return REQS_SUCCESS;
-	if(test_and_clear_bit(CL_ST_CHG_FAIL,&mdev->flags)) return REQS_FAIL;
+	if(test_and_clear_bit(CL_ST_CHG_SUCCESS,&mdev->flags)) 
+		return SS_CW_Success;
 
+	if(test_and_clear_bit(CL_ST_CHG_FAIL,&mdev->flags)) 
+		return SS_CW_FailedByPeer;
+
+	rv=0;
+	spin_lock_irqsave(&mdev->req_lock,flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
+	if( !cl_wide_st_chg(mdev,os,ns) ) rv = SS_CW_NoNeed;
+	if( !rv ) {
+		rv = pre_state_checks(mdev,ns);
+		if(rv==SS_Success) rv = 0; // cont waiting, otherwise fail.
+	}
+	spin_unlock_irqrestore(&mdev->req_lock,flags);
 
-	if(!cl_wide_st_chg(mdev,os,ns)) return REQS_NO_NEED;
-
-	return 0;
+	return rv;
 }
 
-STATIC int drbd_send_state_req(drbd_dev *, drbd_state_t, drbd_state_t);
-
+/** 
+ * _drbd_request_state:
+ * This function is the most gracefull way to change state. For some state
+ * transition this function even does a cluster wide transaction.
+ * It has a cousin named drbd_request_state(), which is always verbose.
+ */ 
 int _drbd_request_state(drbd_dev* mdev, drbd_state_t mask, drbd_state_t val,
 		       enum chg_state_flags f)
 {
@@ -597,17 +614,24 @@
 	ns.i = (os.i & ~mask.i) | val.i;
 
 	if(cl_wide_st_chg(mdev,os,ns)) {
-		// TODO do the pre checks here as well ;
+		rv = pre_state_checks(mdev,ns);
 		spin_unlock_irqrestore(&mdev->req_lock,flags);
 
+		if( rv < SS_Success ) {
+			if( f & ChgStateVerbose ) print_st_err(mdev,os,ns,rv);
+			return rv;
+		}
+
 		drbd_state_lock(mdev);
 		drbd_send_state_req(mdev,mask,val);
 
 		wait_event(mdev->cstate_wait,(rv=_req_st_cond(mdev,mask,val)));
 
-		if(rv == REQS_FAIL) {
+		if( rv < SS_Success ) {
+			// nearly dead code.
 			drbd_state_unlock(mdev);
-			return SS_FailedByPeer; // Nearly dead code ;)
+			if( f & ChgStateVerbose ) print_st_err(mdev,os,ns,rv);
+			return rv;
 		}
 		spin_lock_irqsave(&mdev->req_lock,flags);
 		os = mdev->state;

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2006-05-22 15:10:53 UTC (rev 2205)
+++ trunk/drbd/drbd_strings.c	2006-05-22 18:58:45 UTC (rev 2206)
@@ -68,7 +68,7 @@
 	[-SS_SyncingDiskless] = "Refusing to be syncing and diskless",
 	[-SS_ConnectedOutdates] = "Refusing to be Outdated while Connected",
 	[-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated",
-	[-SS_FailedByPeer] = "State changed was refused by peer node"
+	[-SS_CW_FailedByPeer] = "State changed was refused by peer node"
 };
 
 const char* conns_to_name(drbd_conns_t s) {
@@ -88,7 +88,7 @@
 }
 
 const char* set_st_err_name(set_st_err_t err) {
-	return err < SS_PrimaryNOP ? "TOO_SMALL" :
+	return err < SS_CW_FailedByPeer ? "TOO_SMALL" :
 	       err > SS_TowPrimaries ? "TOO_LARGE"
 		        : drbd_state_sw_errors[-err];
 }

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-05-22 15:10:53 UTC (rev 2205)
+++ trunk/drbd/linux/drbd.h	2006-05-22 18:58:45 UTC (rev 2206)
@@ -260,16 +260,18 @@
 } drbd_state_t;
 
 typedef enum {
+	SS_CW_NoNeed=4,
+	SS_CW_Success=3,
 	SS_NothingToDo=2,
 	SS_Success=1,
-	SS_UnknownError=0,
+	SS_UnknownError=0, // Used to sleep longer in _drbd_request_state
 	SS_TowPrimaries=-1,
 	SS_NoConsistnetDisk=-2,
 	SS_BothInconsistent=-4,
 	SS_SyncingDiskless=-5,
 	SS_ConnectedOutdates=-6,
 	SS_PrimaryNOP=-7,
-	SS_FailedByPeer=-8
+	SS_CW_FailedByPeer=-8
 } set_st_err_t;
 
 /* from drbd_strings.c */



More information about the drbd-cvs mailing list