[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