[DRBD-cvs] r1624 - in trunk: drbd drbd/linux user
svn at svn.drbd.org
svn at svn.drbd.org
Wed Nov 3 16:57:33 CET 2004
Author: phil
Date: 2004-11-03 16:57:30 +0100 (Wed, 03 Nov 2004)
New Revision: 1624
Modified:
trunk/drbd/Makefile
trunk/drbd/drbd_actlog.c
trunk/drbd/drbd_fs.c
trunk/drbd/drbd_int.h
trunk/drbd/drbd_main.c
trunk/drbd/drbd_proc.c
trunk/drbd/drbd_receiver.c
trunk/drbd/drbd_req.c
trunk/drbd/drbd_strings.c
trunk/drbd/drbd_worker.c
trunk/drbd/linux/drbd.h
trunk/user/drbdsetup.c
Log:
* Introduced a new datatype to reflect the state of the
whole cluster.
* Replaced set_cstate() by drbd_request_state() and
drbd_force_state().
* Removed DISKLESS, PARTNER_DISKLESS and
PARTNER_CONSISTENT bits.
* Have a central function where the cluster state is
checked.
It compiles. It completely untested. Will beginn testing
and debugging tomorrow (2004-11-04)
Modified: trunk/drbd/Makefile
===================================================================
--- trunk/drbd/Makefile 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/Makefile 2004-11-03 15:57:30 UTC (rev 1624)
@@ -74,7 +74,7 @@
SRC_FILES := $(shell ls 2>/dev/null\
linux/drbd_config.h linux/drbd.h drbd_actlog.c drbd_bitmap.c drbd_fs.c \
drbd_main.c drbd_proc.c drbd_receiver.c drbd_req.c drbd_worker.c \
- lru_cache.c drbd_compat_wrappers.h drbd_int.h \
+ drbd_strings.c lru_cache.c drbd_compat_wrappers.h drbd_int.h \
lru_cache.h )
.PHONY: drbd.o default all greeting clean kbuild install dep
Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_actlog.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -218,7 +218,7 @@
evicted = al_ext->lc_number;
- if(mdev->cstate < Connected && evicted != LC_FREE ) {
+ if(mdev->state.s.conn < Connected && evicted != LC_FREE ) {
drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT );
}
drbd_al_write_transaction(mdev,al_ext,enr);
@@ -547,8 +547,8 @@
kfree(udw);
if(drbd_bm_total_weight(mdev) == 0 &&
- ( mdev->cstate == SyncSource || mdev->cstate == SyncTarget ||
- mdev->cstate == PausedSyncS || mdev->cstate == PausedSyncT ) ) {
+ ( mdev->state.s.conn == SyncSource || mdev->state.s.conn == SyncTarget ||
+ mdev->state.s.conn == PausedSyncS || mdev->state.s.conn == PausedSyncT ) ) {
D_ASSERT( mdev->resync_work.cb == w_resync_inactive );
drbd_bm_lock(mdev);
drbd_resync_finished(mdev);
@@ -588,7 +588,7 @@
(unsigned long)sector,
ext->lce.lc_number, ext->rs_left, cleared);
// FIXME brrrgs. should never happen!
- _set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return;
}
@@ -651,16 +651,7 @@
unsigned long sbnr,ebnr,lbnr,bnr;
unsigned long count = 0;
sector_t esector, nr_sectors;
- int strange_state;
- strange_state = (mdev->cstate <= Connected) ||
- test_bit(DISKLESS,&mdev->flags) ||
- test_bit(PARTNER_DISKLESS,&mdev->flags);
- if (strange_state) {
- ERR("%s:%d: %s flags=0x%02lx\n", file , line ,
- cstate_to_name(mdev->cstate), mdev->flags);
- }
-
if (size <= 0 || (size & 0x1ff) != 0 || size > PAGE_SIZE) {
ERR("drbd_set_in_sync: sector=%lu size=%d nonsense!\n",
(unsigned long)sector,size);
@@ -727,17 +718,7 @@
{
unsigned long sbnr,ebnr,lbnr,bnr;
sector_t esector, nr_sectors;
- int strange_state;
- strange_state = ( mdev->cstate > Connected ) ||
- ( mdev->cstate == Connected &&
- !(test_bit(DISKLESS,&mdev->flags) ||
- test_bit(PARTNER_DISKLESS,&mdev->flags)) );
- if (strange_state) {
- ERR("%s:%d: %s flags=0x%02lx\n", file , line ,
- cstate_to_name(mdev->cstate), mdev->flags);
- }
-
if (size <= 0 || (size & 0x1ff) != 0 || size > PAGE_SIZE) {
ERR("sector: %lu, size: %d\n",(unsigned long)sector,size);
return;
Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_fs.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -215,7 +215,7 @@
int drbd_ioctl_set_disk(struct Drbd_Conf *mdev,
struct ioctl_disk_config * arg)
{
- int i, md_gc_valid, minor, mput=0;
+ int i, md_gc_valid, minor;
enum ret_codes retcode;
struct disk_config new_conf;
struct file *filp = 0;
@@ -227,7 +227,7 @@
/* if you want to reconfigure, please tear down first */
smp_rmb();
- if (!test_bit(DISKLESS,&mdev->flags))
+ if (mdev->state.s.disk > Diskless)
return -EBUSY;
/* if this was "adding" a lo dev to a previously "diskless" node,
@@ -235,7 +235,7 @@
* if it was mounted, we had an open_cnt > 1,
* so it would be BUSY anyways...
*/
- ERR_IF (mdev->state != Secondary)
+ ERR_IF (mdev->state.s.role != Secondary)
return -EBUSY;
if (mdev->open_cnt > 1)
@@ -257,20 +257,14 @@
*
*/
- if (mdev->cstate == Unconfigured) {
- // ioctl already has a refcnt
- __module_get(THIS_MODULE);
- mput = 1;
- } else {
- /* FIXME allow reattach while connected,
- * and allow it in Primary/Diskless state...
- * currently there are strange races leading to a distributed
- * deadlock in that case...
- */
- if ( mdev->cstate != StandAlone /* &&
- mdev->cstate != Connected */) {
- return -EBUSY;
- }
+
+ /* FIXME allow reattach while connected,
+ * and allow it in Primary/Diskless state...
+ * currently there are strange races leading to a distributed
+ * deadlock in that case...
+ */
+ if ( mdev->state.s.conn > StandAlone ) {
+ return -EBUSY;
}
if ( new_conf.meta_index < -1) {
@@ -387,7 +381,6 @@
D_ASSERT(q->hardsect_size <= PAGE_SIZE); // or we are really screwed ;-)
#undef min_not_zero
- clear_bit(SENT_DISK_FAILURE,&mdev->flags);
set_bit(MD_IO_ALLOWED,&mdev->flags);
/* FIXME I think inc_local_md_only within drbd_md_read is misplaced.
@@ -441,24 +434,15 @@
drbd_set_blocksize(mdev,INITIAL_BLOCK_SIZE);
- if(mdev->cstate == Unconfigured ) {
+ if (drbd_request_state(mdev,NS(disk,
+ drbd_md_test_flag(mdev,MDF_Consistent) ?
+ Consistent : Inconsistent ))) {
drbd_thread_start(&mdev->worker);
- set_cstate(mdev,StandAlone);
}
-
- clear_bit(DISKLESS,&mdev->flags);
- smp_wmb();
// FIXME EXPLAIN:
clear_bit(MD_IO_ALLOWED,&mdev->flags);
- /* FIXME currently only StandAlone here...
- * Connected is not possible, since
- * above we return -EBUSY in that case */
- D_ASSERT(mdev->cstate <= Connected);
- if(mdev->cstate == Connected ) {
- drbd_send_param(mdev,1);
- }
drbd_bm_unlock(mdev);
return 0;
@@ -468,7 +452,6 @@
release_bdev_fail_ioctl:
bd_release(bdev);
fail_ioctl:
- if (mput) module_put(THIS_MODULE);
if (filp) fput(filp);
if (filp2) fput(filp2);
if (put_user(retcode, &arg->ret_code)) return -EFAULT;
@@ -491,10 +474,7 @@
cn.meta_device_minor = MINOR(mdev->md_bdev->bd_dev);
bdevname(mdev->md_bdev,cn.meta_device_name);
}
- cn.cstate=mdev->cstate;
cn.state=mdev->state;
- cn.peer_state=mdev->o_state;
- cn.disk_size_user=mdev->lo_usize;
cn.meta_index=mdev->md_index;
cn.on_io_error=mdev->on_io_error;
memcpy(&cn.nconf, &mdev->conf, sizeof(struct net_config));
@@ -510,7 +490,7 @@
STATIC
int drbd_ioctl_set_net(struct Drbd_Conf *mdev, struct ioctl_net_config * arg)
{
- int i,minor, mput=0;
+ int i,minor;
enum ret_codes retcode;
struct net_config new_conf;
@@ -520,24 +500,18 @@
if (copy_from_user(&new_conf, &arg->config,sizeof(struct net_config)))
return -EFAULT;
- if (mdev->cstate == Unconfigured) {
- // ioctl already has a refcnt
- __module_get(THIS_MODULE);
- mput = 1;
- }
-
#define M_ADDR(A) (((struct sockaddr_in *)&A.my_addr)->sin_addr.s_addr)
#define M_PORT(A) (((struct sockaddr_in *)&A.my_addr)->sin_port)
#define O_ADDR(A) (((struct sockaddr_in *)&A.other_addr)->sin_addr.s_addr)
#define O_PORT(A) (((struct sockaddr_in *)&A.other_addr)->sin_port)
for(i=0;i<minor_count;i++) {
- if( i!=minor && drbd_conf[i].cstate!=Unconfigured &&
+ if( i!=minor && drbd_conf[i].state.s.conn==Unconfigured &&
M_ADDR(new_conf) == M_ADDR(drbd_conf[i].conf) &&
M_PORT(new_conf) == M_PORT(drbd_conf[i].conf) ) {
retcode=LAAlreadyInUse;
goto fail_ioctl;
}
- if( i!=minor && drbd_conf[i].cstate!=Unconfigured &&
+ if( i!=minor && drbd_conf[i].state.s.conn!=Unconfigured &&
O_ADDR(new_conf) == O_ADDR(drbd_conf[i].conf) &&
O_PORT(new_conf) == O_PORT(drbd_conf[i].conf) ) {
retcode=OAAlreadyInUse;
@@ -590,35 +564,27 @@
mdev->recv_cnt = 0;
drbd_thread_start(&mdev->worker);
- set_cstate(mdev,Unconnected);
+ drbd_request_state(mdev,NS(conn,Unconnected));
drbd_thread_start(&mdev->receiver);
return 0;
fail_ioctl:
- if (mput) module_put(THIS_MODULE);
if (put_user(retcode, &arg->ret_code)) return -EFAULT;
return -EINVAL;
}
-int drbd_set_state(drbd_dev *mdev,Drbd_State newstate)
+int drbd_set_state(drbd_dev *mdev,drbd_role_t newstate)
{
- int forced = 0;
- int dont_have_good_data;
+ int r;
D_ASSERT(semaphore_is_locked(&mdev->device_mutex));
- if ( (newstate & 0x3) == mdev->state ) return 0; /* nothing to do */
+ if ( (newstate & 0x3) == mdev->state.s.role ) return 0; /* nothing to do */
// exactly one of sec or pri. not both.
if ( !((newstate ^ (newstate >> 1)) & 1) ) return -EINVAL;
- if(mdev->cstate == Unconfigured)
- return -ENXIO;
-
- if ( (newstate & Primary) && (mdev->o_state == Primary) )
- return -EACCES;
-
ERR_IF (mdev->this_bdev->bd_contains == 0) {
// FIXME this masks a bug somewhere else!
mdev->this_bdev->bd_contains = mdev->this_bdev;
@@ -632,47 +598,32 @@
return -EBUSY;
}
- /* I dont have access to good data anywhere, if:
- * ( I am diskless OR inconsistent )
- * AND
- * ( not connected, or partner has no consistent data either )
- */
- dont_have_good_data =
- ( test_bit(DISKLESS, &mdev->flags)
- || !drbd_md_test_flag(mdev,MDF_Consistent) )
- &&
- ( mdev->cstate < Connected
- || test_bit(PARTNER_DISKLESS, &mdev->flags)
- || !test_bit(PARTNER_CONSISTENT, &mdev->flags) );
-
- if (newstate & Primary) {
- if ( test_bit(DISKLESS,&mdev->flags)
- && mdev->cstate < Connected ) {
- /* not even brute force can find data without disk.
- * FIXME choose a usefull Error,
- * and update drbsetup accordingly */
+ r = drbd_request_state(mdev,NS(role,newstate & 0x3));
+ if ( r == 2 ) { return 0; }
+ if ( r == 0 ) {
+ /* request state does not like the new state. */
+ if (! (newstate & DontBlameDrbd)) {
return -EIO;
- } else if (dont_have_good_data) {
- /* ok, either we have a disk (which may be inconsistent)
- * or we have a connection */
- if (newstate & DontBlameDrbd) {
- forced = 1;
- /* make sure the Human count is increased if
- * we got here only because it was forced.
- * maybe we want to force a FullSync? */
- newstate |= Human;
- } else {
- return -EIO;
- }
- } else if (mdev->cstate >= Connected) {
- /* do NOT increase the Human count if we are connected,
- * and there is no reason for it. See
- * drbd_lk9.pdf middle of Page 7
- */
- newstate &= ~(Human|DontBlameDrbd);
}
+
+ /* --do-what-I-say*/
+ if (mdev->state.s.disk < Consistent) {
+ WARN("Forcefully set consistent!");
+ r = drbd_request_state(mdev,NS2(role,newstate & 0x3,
+ disk,Consistent));
+ if(r==0) return -EIO;
+ }
}
+ if (mdev->state.s.conn >= Connected) {
+ /* do NOT increase the Human count if we are connected,
+ * and there is no reason for it. See
+ * drbd_lk9.pdf middle of Page 7
+ */
+ newstate &= ~(Human|DontBlameDrbd);
+ }
+
+
drbd_sync_me(mdev);
/* Wait until nothing is on the fly :) */
@@ -691,25 +642,8 @@
* but that means someone is misusing DRBD...
* */
- if (forced) { /* this was --do-what-I-say ... */
- int i;
- // drbd_dump_md(mdev,0,0);
- for (i=HumanCnt; i < GEN_CNT_SIZE ; i++) {
- if (mdev->gen_cnt[i] != 1) {
- WARN("Forcefully set consistent! "
- "If this screws your data, don't blame DRBD!\n");
- break;
- }
- }
- drbd_md_set_flag(mdev,MDF_Consistent);
- }
set_bit(MD_DIRTY,&mdev->flags); // we are changing state!
- INFO( "%s/%s --> %s/%s\n",
- nodestate_to_name(mdev->state),
- nodestate_to_name(mdev->o_state),
- nodestate_to_name(newstate & 0x03),
- nodestate_to_name(mdev->o_state) );
- mdev->state = (Drbd_State) newstate & 0x03;
+
if (newstate & Secondary) {
set_disk_ro(mdev->vdisk, TRUE );
} else {
@@ -734,22 +668,17 @@
drbd_md_inc(mdev,TimeoutCnt);
} else {
drbd_md_inc(mdev,
- mdev->cstate >= Connected ?
- ConnectedCnt : ArbitraryCnt);
+ mdev->state.s.conn >= Connected ?
+ ConnectedCnt : ArbitraryCnt);
}
}
- if(!test_bit(DISKLESS,&mdev->flags) && (newstate & Secondary)) {
+ if(mdev->state.s.disk > Diskless && (newstate & Secondary)) {
drbd_al_to_on_disk_bm(mdev);
}
/* Primary indicator has changed in any case. */
drbd_md_write(mdev);
- if (mdev->cstate >= WFReportParams) {
- /* if this was forced, we should consider sync */
- drbd_send_param(mdev,forced);
- }
-
return 0;
}
@@ -806,7 +735,7 @@
err = drbd_check_al_size(mdev);
if (err) return err;
- if (mdev->cstate > WFConnection)
+ if (mdev->state.s.conn >= Connected)
drbd_send_sync_param(mdev,&sc);
drbd_alter_sg(mdev, sc.group);
@@ -814,51 +743,33 @@
return 0;
}
+/* new */
STATIC int drbd_detach_ioctl(drbd_dev *mdev)
{
- int would_discard_last_good_data;
- int interrupted;
+ int interrupted,r;
+ drbd_state_t os,ns;
- // not during resync. no.
- if (mdev->cstate > Connected) return -EBUSY;
+ spin_lock_irq(&mdev->req_lock);
+ os = mdev->state;
+ r = _drbd_set_state(mdev,_NS(disk,Diskless),0);
+ ns = mdev->state;
+ spin_unlock_irq(&mdev->req_lock);
- /* this was the last good data copy, if:
- * (I am Primary, and not connected ),
- * OR
- * (we are connected, and Peer has no good data himself)
- */
- would_discard_last_good_data =
- ( mdev->state == Primary && mdev->cstate < Connected )
- ||
- ( mdev->cstate >= Connected
- && ( test_bit(PARTNER_DISKLESS, &mdev->flags)
- || !test_bit(PARTNER_CONSISTENT, &mdev->flags) ) );
+ if( r == 2 ) { return 0; }
+ if( r == 0 ) { return -ENETRESET; }
- if ( would_discard_last_good_data ) {
- return -ENETRESET;
- }
- if (test_bit(DISKLESS,&mdev->flags) ||
- test_bit(PARTNER_DISKLESS,&mdev->flags) ) {
- return -ENXIO;
- }
-
drbd_sync_me(mdev);
- set_bit(DISKLESS,&mdev->flags);
- smp_wmb();
-
interrupted = wait_event_interruptible(mdev->cstate_wait,
atomic_read(&mdev->local_cnt)==0);
if ( interrupted ) {
- clear_bit(DISKLESS,&mdev->flags);
+ drbd_force_state(mdev,NS(disk,os.s.disk));
return -EINTR;
}
drbd_free_ll_dev(mdev);
+ after_state_ch(mdev, os, ns);
-/* FIXME race with sync start
-*/
- if (mdev->cstate == Connected) drbd_send_param(mdev,0);
/* FIXME
* if you detach while connected, you are *at least* inconsistent now,
* and should clear MDF_Consistent in metadata, and maybe even set the bitmap
@@ -866,19 +777,13 @@
* since if you reattach, this might be a different lo dev, and then it needs
* to receive a sync!
*/
- if (mdev->cstate == StandAlone) {
- // maybe < Connected is better?
- set_cstate(mdev,Unconfigured);
- drbd_mdev_cleanup(mdev);
- module_put(THIS_MODULE);
- }
return 0;
}
int drbd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int minor,err=0;
+ int r,minor,err=0;
long time;
struct Drbd_Conf *mdev;
struct ioctl_wait* wp;
@@ -916,44 +821,6 @@
goto out_unlocked;
}
- if (mdev->cstate == Unconfigured) {
- switch (cmd) {
- default:
- /* oops, unknown IOCTL ?? */
- err = -EINVAL;
- goto out_unlocked;
-
- case DRBD_IOCTL_GET_CONFIG:
- case DRBD_IOCTL_GET_VERSION:
- break; /* always allowed */
-
- case DRBD_IOCTL_SET_DISK_CONFIG:
- case DRBD_IOCTL_SET_NET_CONFIG:
- break; /* no restriction here */
-
- case DRBD_IOCTL_UNCONFIG_DISK:
- case DRBD_IOCTL_UNCONFIG_NET:
- /* no op, so "drbdadm down all" does not fail */
- err = 0;
- goto out_unlocked;
-
- /* the rest of them don't make sense if Unconfigured.
- * still, set an Unconfigured device Secondary
- * is allowed, so "drbdadm down all" does not fail */
- case DRBD_IOCTL_SET_STATE:
- case DRBD_IOCTL_INVALIDATE:
- case DRBD_IOCTL_INVALIDATE_REM:
- case DRBD_IOCTL_SET_DISK_SIZE:
- case DRBD_IOCTL_SET_STATE_FLAGS:
- case DRBD_IOCTL_SET_SYNC_CONFIG:
- case DRBD_IOCTL_WAIT_CONNECT:
- case DRBD_IOCTL_WAIT_SYNC:
- err = (cmd == DRBD_IOCTL_SET_STATE && arg == Secondary)
- ? 0 : -ENXIO;
- goto out_unlocked;
- }
- }
-
if (unlikely(drbd_did_panic == DRBD_MAGIC))
return -EBUSY;
@@ -1000,7 +867,7 @@
break;
case DRBD_IOCTL_SET_DISK_SIZE:
- if (mdev->cstate > Connected) {
+ if (mdev->state.s.conn > Connected) {
err = -EBUSY;
break;
}
@@ -1010,7 +877,7 @@
drbd_determin_dev_size(mdev);
drbd_md_write(mdev); // Write mdev->la_size to disk.
drbd_bm_unlock(mdev);
- if (mdev->cstate == Connected) drbd_send_param(mdev,0);
+ if (mdev->state.s.conn == Connected) drbd_send_param(mdev,0);
break;
case DRBD_IOCTL_SET_NET_CONFIG:
@@ -1027,31 +894,31 @@
break;
case DRBD_IOCTL_UNCONFIG_NET:
- if ( mdev->cstate == Unconfigured) break;
- if ( ( mdev->state == Primary
- && test_bit(DISKLESS,&mdev->flags) )
- || ( mdev->o_state == Primary
- && !test_bit(PARTNER_CONSISTENT,&mdev->flags) ) )
- {
+ if ( mdev->state.s.conn == Unconfigured) break;
+
+ r = drbd_request_state(mdev,NS(conn,StandAlone));
+ if( r == 2 ) { break; }
+ if( r == 0 ) {
err=-ENODATA;
break;
- }
- /* FIXME what if fsync returns error */
- drbd_sync_me(mdev);
+ }
+ /* r == 1 which means that we changed the state... */
+
+ drbd_sync_me(mdev); /* FIXME what if fsync returns error */
+
set_bit(DO_NOT_INC_CONCNT,&mdev->flags);
- set_cstate(mdev,Unconnected);
drbd_thread_stop(&mdev->receiver);
- if (test_bit(DISKLESS,&mdev->flags)) {
- set_cstate(mdev,Unconfigured);
- drbd_mdev_cleanup(mdev);
+ if ( mdev->state.s.conn == StandAlone &&
+ mdev->state.s.disk == Diskless ) {
+ drbd_mdev_cleanup(mdev); // Move to after_state_ch() ?
module_put(THIS_MODULE);
- } else set_cstate(mdev,StandAlone);
+ }
break;
case DRBD_IOCTL_UNCONFIG_DISK:
- if (mdev->cstate == Unconfigured) break;
+ if (mdev->state.s.disk == Diskless) break;
err = drbd_detach_ioctl(mdev);
break;
@@ -1064,8 +931,8 @@
time = wait_event_interruptible_timeout(
mdev->cstate_wait,
- mdev->cstate < Unconnected
- || mdev->cstate >= Connected,
+ mdev->state.s.conn < Unconnected
+ || mdev->state.s.conn >= Connected,
time );
if (time < 0) {
err = time;
@@ -1077,7 +944,7 @@
}
err=0; // no error
- if(put_user(mdev->cstate>=Connected,&wp->ret_code))err=-EFAULT;
+ if(put_user(mdev->state.s.conn>=Connected,&wp->ret_code))err=-EFAULT;
goto out_unlocked;
case DRBD_IOCTL_WAIT_SYNC:
@@ -1089,8 +956,8 @@
do {
time = wait_event_interruptible_timeout(
mdev->cstate_wait,
- mdev->cstate == Connected
- || mdev->cstate < Unconnected,
+ mdev->state.s.conn == Connected
+ || mdev->state.s.conn < Unconnected,
time );
if (time < 0 ) {
@@ -1098,7 +965,7 @@
goto out_unlocked;
}
- if (mdev->cstate > Connected) {
+ if (mdev->state.s.conn > Connected) {
time=MAX_SCHEDULE_TIMEOUT;
}
@@ -1106,12 +973,12 @@
err = -ETIME;
goto out_unlocked;
}
- } while ( mdev->cstate != Connected
- && mdev->cstate >= Unconnected );
+ } while ( mdev->state.s.conn != Connected
+ && mdev->state.s.conn >= Unconnected );
err=0; // no error
- if(put_user(mdev->cstate==Connected,&wp->ret_code))err=-EFAULT;
+ if(put_user(mdev->state.s.conn==Connected,&wp->ret_code))err=-EFAULT;
goto out_unlocked;
case DRBD_IOCTL_INVALIDATE:
@@ -1123,23 +990,22 @@
/* disallow "invalidation" of local replica
* when currently in primary state (would be a Bad Idea),
* or during a running sync (won't make any sense) */
- if( mdev->state == Primary ||
- mdev->cstate < StandAlone ||
- mdev->cstate > Connected ||
- test_bit(DISKLESS,&mdev->flags) ||
- test_bit(PARTNER_DISKLESS,&mdev->flags) ) {
+
+ /* PRE TODO disallow invalidate if we are primary */
+ r = drbd_request_state(mdev,NS2(disk,Inconsistent,
+ conn,WFBitMapT));
+
+ if( r == 2 ) { break; }
+ if( r == 0 ) {
err = -EINPROGRESS;
break;
- }
+ }
- if (mdev->cstate == Connected) {
- /* avoid races with set_in_sync
- * for successfull mirrored writes
- */
- set_cstate(mdev,WFBitMapT);
- wait_event(mdev->cstate_wait,
- atomic_read(&mdev->ap_bio_cnt)==0);
- }
+ /* avoid races with set_in_sync
+ * for successfull mirrored writes
+ */
+ wait_event(mdev->cstate_wait,
+ atomic_read(&mdev->ap_bio_cnt)==0);
drbd_bm_lock(mdev); // racy...
@@ -1153,8 +1019,7 @@
drbd_md_clear_flag(mdev,MDF_FullSync);
drbd_md_write(mdev);
- if (mdev->cstate == Connected) {
- drbd_send_short_cmd(mdev,BecomeSyncSource);
+ if (drbd_send_short_cmd(mdev,BecomeSyncSource)) {
drbd_start_resync(mdev,SyncTarget);
}
@@ -1163,18 +1028,17 @@
break;
case DRBD_IOCTL_INVALIDATE_REM:
- if( mdev->o_state == Primary ||
- mdev->cstate != Connected ||
- test_bit(DISKLESS,&mdev->flags) ||
- test_bit(PARTNER_DISKLESS,&mdev->flags) ) {
+
+ /* PRE TODO disallow invalidate if we peer is primary */
+ /* remove EINVAL from error output... */
+ r = drbd_request_state(mdev,NS2(pedi,Inconsistent,
+ conn,WFBitMapS));
+
+ if( r == 2 ) { break; }
+ if( r == 0 ) {
err = -EINPROGRESS;
break;
- }
- if ( !drbd_md_test_flag(mdev,MDF_Consistent) ) {
- // FIXME use a more descriptive error number
- err = -EINVAL;
- break;
- }
+ }
drbd_md_set_flag(mdev,MDF_FullSync);
drbd_md_write(mdev);
@@ -1182,7 +1046,6 @@
/* avoid races with set_in_sync
* for successfull mirrored writes
*/
- set_cstate(mdev,WFBitMapS);
wait_event(mdev->cstate_wait,
atomic_read(&mdev->ap_bio_cnt)==0);
Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_int.h 2004-11-03 15:57:30 UTC (rev 1624)
@@ -613,9 +613,6 @@
ON_PRI_INC_TIMEOUTEX, // When " - " increase timeout-count
UNPLUG_QUEUED, // only relevant with kernel 2.4
UNPLUG_REMOTE, // whether sending a "UnplugRemote" makes sense
- DISKLESS, // no local disk
- PARTNER_DISKLESS, // partner has no storage
- PARTNER_CONSISTENT, // partner has consistent data
PROCESS_EE_RUNNING, // eek!
MD_IO_ALLOWED, // EXPLAIN
SENT_DISK_FAILURE, // sending it once is enough
@@ -678,10 +675,8 @@
int md_index;
sector_t lo_usize; /* user provided size */
sector_t p_size; /* partner's disk size */
- Drbd_State state;
- volatile Drbd_CState cstate;
+ /* volatile */ drbd_state_t state;
wait_queue_head_t cstate_wait; // TODO Rename into "misc_wait".
- Drbd_State o_state;
sector_t la_size; // last agreed disk size in sectors.
unsigned int send_cnt;
unsigned int recv_cnt;
@@ -748,7 +743,8 @@
*************************/
// drbd_main.c
-extern void _set_cstate(drbd_dev* mdev,Drbd_CState cs);
+extern int _drbd_set_state(drbd_dev* mdev, drbd_state_t ns, int hard);
+extern void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns);
extern void 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);
@@ -950,14 +946,14 @@
// drbd_fs.c
extern char* ppsize(char* buf, size_t size);
extern int drbd_determin_dev_size(drbd_dev*);
-extern int drbd_set_state(drbd_dev *mdev,Drbd_State newstate);
+extern int drbd_set_state(drbd_dev *mdev,drbd_role_t newstate);
extern int drbd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
// drbd_dsender.c
extern int drbd_worker(struct Drbd_thread *thi);
extern void drbd_alter_sg(drbd_dev *mdev, int ng);
-extern void drbd_start_resync(drbd_dev *mdev, Drbd_CState side);
+extern void drbd_start_resync(drbd_dev *mdev, drbd_conns_t side);
extern int drbd_resync_finished(drbd_dev *mdev);
// maybe rather drbd_main.c ?
extern int drbd_md_sync_page_io(drbd_dev *mdev, sector_t sector, int rw);
@@ -984,8 +980,8 @@
// drbd_proc.c
extern struct proc_dir_entry *drbd_proc;
extern int drbd_proc_get_info(char *, char **, off_t, int, int *, void *);
-extern const char* cstate_to_name(Drbd_CState s);
-extern const char* nodestate_to_name(Drbd_State s);
+extern const char* cstate_to_name(drbd_conns_t s);
+extern const char* nodestate_to_name(drbd_role_t s);
// drbd_actlog.c
extern void drbd_al_begin_io(struct Drbd_Conf *mdev, sector_t sector);
@@ -1010,14 +1006,57 @@
#include "drbd_compat_wrappers.h"
-static inline void set_cstate(drbd_dev* mdev,Drbd_CState ns)
+#define peer_mask role_mask
+#define pedi_mask disk_mask
+
+#define NS(T,S) ({drbd_state_t mask; mask.i=0; mask.s.T = T##_mask; mask;}), \
+ ({drbd_state_t val; val.i=0; val.s.T = (S); val;})
+#define NS2(T1,S1,T2,S2) \
+ ({drbd_state_t mask; mask.i=0; mask.s.T1 = T1##_mask; \
+ mask.s.T2 = T2##_mask; mask;}), \
+ ({drbd_state_t val; val.i=0; val.s.T1 = (S1); \
+ val.s.T2 = (S2); val;})
+#define NS3(T1,S1,T2,S2,T3,S3) \
+ ({drbd_state_t mask; mask.i=0; mask.s.T1 = T1##_mask; \
+ mask.s.T2 = T2##_mask; mask.s.T3 = T3##_mask; mask;}), \
+ ({drbd_state_t val; val.i=0; val.s.T1 = (S1); \
+ val.s.T2 = (S2); val.s.T3 = (S3); val;})
+
+#define _NS(T,S) ({drbd_state_t ns; ns.i = mdev->state.i; ns.s.T = (S); ns;})
+
+static inline void drbd_force_state(drbd_dev* mdev,
+ drbd_state_t mask, drbd_state_t val)
{
unsigned long flags;
+ drbd_state_t os,ns;
+
spin_lock_irqsave(&mdev->req_lock,flags);
- _set_cstate(mdev,ns);
+ os = mdev->state;
+ ns.i = (os.i & ~mask.i) | val.i;
+ _drbd_set_state(mdev, ns, 1);
+ ns = mdev->state;
spin_unlock_irqrestore(&mdev->req_lock,flags);
+ after_state_ch(mdev,os,ns);
}
+static inline int drbd_request_state(drbd_dev* mdev,
+ drbd_state_t mask, drbd_state_t val)
+{
+ unsigned long flags;
+ drbd_state_t os,ns;
+ int rv;
+
+ spin_lock_irqsave(&mdev->req_lock,flags);
+ os = mdev->state;
+ ns.i = (os.i & ~mask.i) | val.i;
+ rv = _drbd_set_state(mdev, ns, 0);
+ ns = mdev->state;
+ spin_unlock_irqrestore(&mdev->req_lock,flags);
+ after_state_ch(mdev,os,ns);
+
+ return rv;
+}
+
/**
* drbd_chk_io_error: Handles the on_io_error setting, should be called from
* all io completion handlers. See also drbd_io_error().
@@ -1025,30 +1064,25 @@
static inline void drbd_chk_io_error(drbd_dev* mdev, int error)
{
if (error) {
+ unsigned long flags;
+ spin_lock_irqsave(&mdev->req_lock,flags);
+
switch(mdev->on_io_error) {
case PassOn:
ERR("Ignoring local IO error!\n");
break;
case Panic:
- set_bit(DISKLESS,&mdev->flags);
- smp_mb(); // but why is there smp_mb__after_clear_bit() ?
+ _drbd_set_state(mdev,_NS(disk,Failed),1);
drbd_panic("IO error on backing device!\n");
break;
case Detach:
- /*lge:
- * I still do not fully grasp when to set or clear
- * this flag... but I want to be able to at least
- * still _try_ and write the "I am inconsistent, and
- * need full sync" information to the MD. */
set_bit(MD_IO_ALLOWED,&mdev->flags);
- drbd_md_set_flag(mdev,MDF_FullSync);
- drbd_md_clear_flag(mdev,MDF_Consistent);
- if (!test_and_set_bit(DISKLESS,&mdev->flags)) {
- smp_mb(); // Nack is sent in w_e handlers.
+ if (_drbd_set_state(mdev,_NS(disk,Failed),1) == 1) {
ERR("Local IO failed. Detaching...\n");
}
break;
}
+ spin_unlock_irqrestore(&mdev->req_lock,flags);
}
}
@@ -1253,7 +1287,7 @@
int io_allowed;
atomic_inc(&mdev->local_cnt);
- io_allowed = !test_bit(DISKLESS,&mdev->flags);
+ io_allowed = (mdev->state.s.disk >= Inconsistent);
if( !io_allowed ) {
atomic_dec(&mdev->local_cnt);
}
@@ -1265,7 +1299,7 @@
int io_allowed;
atomic_inc(&mdev->local_cnt);
- io_allowed = !test_bit(DISKLESS,&mdev->flags) ||
+ io_allowed = (mdev->state.s.disk >= Inconsistent) ||
test_bit(MD_IO_ALLOWED,&mdev->flags);
if( !io_allowed ) {
atomic_dec(&mdev->local_cnt);
@@ -1276,7 +1310,7 @@
static inline void dec_local(drbd_dev* mdev)
{
if(atomic_dec_and_test(&mdev->local_cnt) &&
- test_bit(DISKLESS,&mdev->flags) &&
+ mdev->state.s.disk == Diskless &&
mdev->lo_file) {
wake_up(&mdev->cstate_wait);
}
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_main.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -331,12 +331,20 @@
*/
int drbd_io_error(drbd_dev* mdev)
{
- int ok=1;
+ unsigned long flags;
+ int send,ok=1;
if(mdev->on_io_error != Panic && mdev->on_io_error != Detach) return 1;
- if(test_and_set_bit(SENT_DISK_FAILURE,&mdev->flags)) return 1;
- D_ASSERT(test_bit(DISKLESS,&mdev->flags));
+ spin_lock_irqsave(&mdev->req_lock,flags);
+ if( (send = (mdev->state.s.disk == Failed)) ) {
+ _drbd_set_state(mdev,_NS(disk,Diskless),1);
+ }
+ D_ASSERT(mdev->state.s.disk <= Failed);
+ spin_unlock_irqrestore(&mdev->req_lock,flags);
+
+ if(!send) return ok;
+
ok = drbd_send_param(mdev,0);
WARN("Notified peer that my disk is broken.\n");
@@ -347,11 +355,6 @@
drbd_md_write(mdev);
}
- if(mdev->cstate > Connected ) {
- WARN("Resync aborted.\n");
- set_cstate(mdev,Connected);
- mdev->rs_total = 0;
- }
if ( wait_event_interruptible_timeout(mdev->cstate_wait,
atomic_read(&mdev->local_cnt) == 0 , HZ ) <= 0) {
WARN("Not releasing backing storage device.\n");
@@ -371,36 +374,138 @@
return ok;
}
-void _set_cstate(drbd_dev* mdev,Drbd_CState ns)
+#define drbd_peer_s_names drbd_role_s_names
+#define drbd_pedi_s_names drbd_disk_s_names
+
+#define PSC(A) \
+ ({ if( ns.s.A != os.s.A ) { \
+ pbp += sprintf(pbp, #A "( %s -> %s ) ", \
+ drbd_##A##_s_names[os.s.A], \
+ drbd_##A##_s_names[ns.s.A]); \
+ } })
+
+
+/* PRE TODO: Should return ernno numbers from the pre-state-change checks. */
+int _drbd_set_state(drbd_dev* mdev, drbd_state_t ns, int hard)
{
- Drbd_CState os;
+ drbd_state_t os;
+ char pb[160], *pbp;
- os = mdev->cstate;
+ os = mdev->state;
+ if( ns.i == os.i ) return 2;
+
+ if( !hard ) {
+ /* pre-state-change checks ; only look at ns */
+ if( !ns.s.mult &&
+ ns.s.role == Primary && ns.s.peer == Primary ) {
+ WARN("Multiple primaries now allowed by config.");
+ return 0;
+ }
+
+ if( ns.s.role == Primary && ns.s.disk <= Inconsistent &&
+ ns.s.conn < Connected ) {
+ WARN("Refusing to be Primary without consistent data");
+ return 0;
+ }
+
+ if( ns.s.peer == Primary && ns.s.pedi <= Inconsistent &&
+ ns.s.conn < Connected ) {
+ WARN("Refusing to make peer Primary without data");
+ return 0;
+ }
+
+ if( ns.s.disk < Consistent && ns.s.pedi < Consistent ) {
+ WARN("Refusing to be inconsistent on both nodes.");
+ return 0;
+ }
+
+ if( ns.s.conn > Connected &&
+ (ns.s.disk == Diskless || ns.s.pedi == Diskless ) ) {
+ WARN("Refusing to do resync without two disks.");
+ return 0;
+ }
+ }
+
+ /* State sanitising */
+ if( ns.s.conn < Connected ) ns.s.peer = Unknown;
+ if( ns.s.conn < Connected ) ns.s.pedi = DUnknown;
+
+ if( ns.s.disk <= Failed && ns.s.conn > Connected) {
+ WARN("Resync aborted.\n");
+ ns.s.conn = Connected;
+ }
+
#if DUMP_MD >= 2
- INFO("%s [%d]: cstate %s --> %s\n", current->comm, current->pid,
- cstate_to_name(os), cstate_to_name(ns) );
+ pbp = pb;
+ PSC(role);
+ PSC(peer);
+ PSC(conn);
+ PSC(disk);
+ PSC(pedi);
+ if( ns.s.mult != os.s.mult ) {
+ sprintf(pbp, "mult( %d -> %d)", os.s.mult,ns.s.mult);
+ }
+ INFO("%s\n", pb);
#endif
- mdev->cstate = ns;
- smp_mb();
+ mdev->state.i = ns.i;
wake_up(&mdev->cstate_wait);
- /* THINK.
- * was:
- * if ( ( os==SyncSource || os==SyncTarget ) && ns <= Connected ) {
- */
- if ( ( os >= SyncSource ) && ns <= Connected ) {
+ /** post-state-change actions **/
+ if ( os.s.conn >= SyncSource && ns.s.conn <= Connected ) {
set_bit(STOP_SYNC_TIMER,&mdev->flags);
mod_timer(&mdev->resync_timer,jiffies);
}
- if(test_bit(MD_IO_ALLOWED,&mdev->flags) &&
- test_bit(DISKLESS,&mdev->flags) && ns < Connected) {
-// FIXME EXPLAIN
- clear_bit(MD_IO_ALLOWED,&mdev->flags);
+
+ if ( os.s.peer == Secondary && ns.s.peer == Primary ) {
+ drbd_md_inc(mdev,ConnectedCnt);
}
+
+ if ( os.s.disk == Diskless && os.s.peer == StandAlone &&
+ (ns.s.disk >= Inconsistent || ns.s.peer > StandAlone) ) {
+ __module_get(THIS_MODULE);
+ }
+
+ if ( ns.s.role == Primary && ns.s.conn < Connected &&
+ ns.s.disk < Consistent ) {
+ drbd_panic("No access to good data anymore.\n");
+ }
+
+ return 1;
}
+void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns)
+{
+ /* Here we have the actions that are performed after a
+ state change. This function might sleep */
+
+ /* Added disk, tell peer. */
+ if ( os.s.disk == Diskless && ns.s.disk >= Inconsistent &&
+ ns.s.conn >= Connected ) {
+ drbd_send_param(mdev,1);
+ }
+
+ /* Removed disk, tell peer. */
+ if ( os.s.disk >= Inconsistent && ns.s.disk == Diskless &&
+ ns.s.conn >= Connected ) {
+ drbd_send_param(mdev,0);
+ }
+
+ /* Update MDF_Consistent in the meta-data */
+ if ( os.s.disk != ns.s.disk && ns.s.disk > Failed ) {
+ if(ns.s.disk >= Outdated ) {
+ drbd_md_set_flag(mdev,MDF_Consistent);
+ } else {
+ drbd_md_clear_flag(mdev,MDF_Consistent);
+ }
+ /* TODO metadata, to support everything that
+ drbd_disk_t can express... */
+ }
+
+}
+
+
STATIC int drbd_thread_setup(void* arg)
{
struct Drbd_thread *thi = (struct Drbd_thread *) arg;
@@ -610,11 +715,12 @@
ok = drbd_send_cmd(mdev,mdev->data.socket,SyncParam,(Drbd_Header*)&p,sizeof(p));
if ( ok
- && (mdev->cstate == SkippedSyncS || mdev->cstate == SkippedSyncT)
- && !sc->skip )
+ && (mdev->state.s.conn == SkippedSyncS ||
+ mdev->state.s.conn == SkippedSyncT)
+ && !sc->skip )
{
/* FIXME EXPLAIN. I think this cannot work properly! -lge */
- set_cstate(mdev,WFReportParams);
+ drbd_request_state(mdev,NS(conn,WFReportParams));
ok = drbd_send_param(mdev,0);
}
return ok;
@@ -636,7 +742,7 @@
p.u_size = cpu_to_be64(mdev->lo_usize);
p.p_size = cpu_to_be64(m_size);
- p.state = cpu_to_be32(mdev->state);
+ p.state = cpu_to_be32(mdev->state.i);
p.protocol = cpu_to_be32(mdev->conf.wire_protocol);
p.version = cpu_to_be32(PRO_VERSION);
@@ -673,7 +779,7 @@
if (drbd_md_test_flag(mdev,MDF_FullSync)) {
drbd_bm_set_all(mdev);
drbd_bm_write(mdev);
- if (unlikely(test_bit(DISKLESS,&mdev->flags))) {
+ if (unlikely(mdev->state.s.disk <= Failed )) {
/* write_bm did fail! panic.
* FIXME can we do something better than panic?
*/
@@ -752,8 +858,8 @@
p.block_id = e->block_id;
p.blksize = cpu_to_be32(drbd_ee_get_size(e));
- if (!mdev->meta.socket || mdev->cstate < Connected) return FALSE;
- ok = drbd_send_cmd(mdev,mdev->meta.socket,cmd,(Drbd_Header*)&p,sizeof(p));
+ if (!mdev->meta.socket || mdev->state.s.conn < Connected) return FALSE;
+ ok=drbd_send_cmd(mdev,mdev->meta.socket,cmd,(Drbd_Header*)&p,sizeof(p));
return ok;
}
@@ -784,7 +890,7 @@
drop_it = mdev->meta.socket == sock
|| !mdev->asender.task
|| get_t_state(&mdev->asender) != Running
- || (volatile int)mdev->cstate < Connected;
+ || (volatile int)mdev->state.s.conn < Connected;
if (drop_it)
return TRUE;
@@ -1077,7 +1183,7 @@
int rv,sent=0;
if (!sock) return -1000;
- if ((volatile int)mdev->cstate < WFReportParams) return -1001;
+ if ((volatile int)mdev->state.s.conn < WFReportParams) return -1001;
// THINK if (signal_pending) return ... ?
@@ -1153,9 +1259,9 @@
ERR("%s_sendmsg returned %d\n",
sock == mdev->meta.socket ? "msock" : "sock",
rv);
- set_cstate(mdev, BrokenPipe);
+ drbd_force_state(mdev, NS(conn,BrokenPipe));
} else
- set_cstate(mdev, Timeout);
+ drbd_force_state(mdev, NS(conn,Timeout));
drbd_thread_restart_nowait(&mdev->receiver);
}
@@ -1170,7 +1276,7 @@
if(minor >= minor_count) return -ENODEV;
if (file->f_mode & FMODE_WRITE) {
- if( drbd_conf[minor].state == Secondary) {
+ if( drbd_conf[minor].state.s.role == Secondary) {
return -EROFS;
}
set_bit(WRITER_PRESENT, &drbd_conf[minor].flags);
@@ -1212,31 +1318,34 @@
spin_unlock_irq(q->queue_lock);
/* only if connected */
- if (mdev->cstate >= Connected && !test_bit(PARTNER_DISKLESS,&mdev->flags)) {
- D_ASSERT(mdev->state == Primary);
+ spin_lock_irq(&mdev->req_lock);
+ if (mdev->state.s.pedi >= Inconsistent) /* implies cs >= Connected */ {
+ D_ASSERT(mdev->state.s.role == Primary);
if (test_and_clear_bit(UNPLUG_REMOTE,&mdev->flags)) {
- spin_lock_irq(&mdev->req_lock);
/* add to the front of the data.work queue,
* unless already queued.
* XXX this might be a good addition to drbd_queue_work
* anyways, to detect "double queuing" ... */
if (list_empty(&mdev->unplug_work.list))
_drbd_queue_work_front(&mdev->data.work,&mdev->unplug_work);
- spin_unlock_irq(&mdev->req_lock);
}
}
+ spin_unlock_irq(&mdev->req_lock);
- if(!test_bit(DISKLESS,&mdev->flags)) drbd_kick_lo(mdev);
+ if(mdev->state.s.disk >= Inconsistent) drbd_kick_lo(mdev);
}
void drbd_set_defaults(drbd_dev *mdev)
{
- mdev->flags = 1<<DISKLESS;
mdev->sync_conf.rate = 250;
mdev->sync_conf.al_extents = 127; // 512 MB active set
- mdev->state = Secondary;
- mdev->o_state = Unknown;
- mdev->cstate = Unconfigured;
+ mdev->state = (drbd_state_t){ { Secondary,
+ Unknown,
+ StandAlone,
+ Diskless,
+ DUnknown,
+ 0,
+ 0 } };
}
void drbd_init_set_defaults(drbd_dev *mdev)
@@ -1841,8 +1950,8 @@
memset(buffer,0,512);
flags = mdev->gen_cnt[Flags] & ~(MDF_PrimaryInd|MDF_ConnectedInd);
- if (mdev->state == Primary) flags |= MDF_PrimaryInd;
- if (mdev->cstate >= WFReportParams) flags |= MDF_ConnectedInd;
+ if (mdev->state.s.role == Primary) flags |= MDF_PrimaryInd;
+ if (mdev->state.s.conn >= WFReportParams) flags |= MDF_ConnectedInd;
mdev->gen_cnt[Flags] = flags;
for (i = Flags; i < GEN_CNT_SIZE; i++)
@@ -1870,7 +1979,7 @@
if (drbd_md_sync_page_io(mdev,sector,WRITE)) {
clear_bit(MD_DIRTY,&mdev->flags);
} else {
- if (test_bit(DISKLESS,&mdev->flags)) {
+ if (mdev->state.s.disk <= Failed) {
/* this was a try anyways ... */
ERR("meta data update failed!\n");
} else {
@@ -1958,7 +2067,7 @@
void drbd_dump_md(drbd_dev *mdev, Drbd_Parameter_Packet *peer, int verbose)
{
INFO("I am(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
- mdev->state == Primary ? 'P':'S',
+ mdev->state.s.role == Primary ? 'P':'S',
MeGC(Flags) & MDF_Consistent ? '1' : '0',
MeGC(HumanCnt),
MeGC(TimeoutCnt),
@@ -1968,7 +2077,7 @@
MeGC(Flags) & MDF_ConnectedInd ? '1' : '0');
if (peer) {
INFO("Peer(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
- be32_to_cpu(peer->state) == Primary ? 'P':'S',
+ ((drbd_state_t)be32_to_cpu(peer->state)).s.role == Primary ? 'P':'S',
PeGC(Flags) & MDF_Consistent ? '1' : '0',
PeGC(HumanCnt),
PeGC(TimeoutCnt),
Modified: trunk/drbd/drbd_proc.c
===================================================================
--- trunk/drbd/drbd_proc.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_proc.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -146,44 +146,24 @@
return sz;
}
-const char* cstate_to_name(Drbd_CState s) {
- static const char *cstate_names[] = {
- [Unconfigured] = "Unconfigured",
- [StandAlone] = "StandAlone",
- [Unconnected] = "Unconnected",
- [Timeout] = "Timeout",
- [BrokenPipe] = "BrokenPipe",
- [NetworkFailure] = "NetworkFailure",
- [WFConnection] = "WFConnection",
- [WFReportParams] = "WFReportParams",
- [Connected] = "Connected",
- [SkippedSyncS] = "SkippedSyncS",
- [SkippedSyncT] = "SkippedSyncT",
- [WFBitMapS] = "WFBitMapS",
- [WFBitMapT] = "WFBitMapT",
- [SyncSource] = "SyncSource",
- [SyncTarget] = "SyncTarget",
- [PausedSyncS] = "PausedSyncS",
- [PausedSyncT] = "PausedSyncT",
- };
-
+const char* cstate_to_name(drbd_conns_t s) {
return s < Unconfigured ? "TO_SMALL" :
s > PausedSyncT ? "TO_LARGE"
- : cstate_names[s];
+ : drbd_conn_s_names[s];
}
-const char* nodestate_to_name(Drbd_State s) {
- static const char *state_names[] = {
- [Primary] = "Primary",
- [Secondary] = "Secondary",
- [Unknown] = "Unknown"
- };
-
+const char* nodestate_to_name(drbd_role_t s) {
return s < Unknown ? "TO_SMALL" :
s > Secondary ? "TO_LARGE"
- : state_names[s];
+ : drbd_role_s_names[s];
}
+const char* diskstate_to_name(drbd_disks_t s) {
+ return s < DUnknown ? "TO_SMALL" :
+ s > UpToDate ? "TO_LARGE"
+ : drbd_disk_s_names[s];
+}
+
/* FIXME we should use snprintf, we only have guaranteed room for one page...
* we should eventually use seq_file for this */
int drbd_proc_get_info(char *buf, char **start, off_t offset,
@@ -209,27 +189,30 @@
*/
for (i = 0; i < minor_count; i++) {
- sn = cstate_to_name(drbd_conf[i].cstate);
+ sn = cstate_to_name(drbd_conf[i].state.s.conn);
+
+ /* PRE FIXME
if(drbd_conf[i].cstate == Connected) {
if(test_bit(DISKLESS,&drbd_conf[i].flags))
sn = "DiskLessClient";
if(test_bit(PARTNER_DISKLESS,&drbd_conf[i].flags))
sn = "ServerForDLess";
- }
- if ( drbd_conf[i].cstate == Unconfigured ) {
+ } */
+
+ if ( drbd_conf[i].state.s.conn == StandAlone &&
+ drbd_conf[i].state.s.disk == Diskless) {
rlen += sprintf( buf + rlen,
- "%2d: cs:Unconfigured\n", i);
+ "%2d: Unconfigured\n", i);
} else {
rlen += sprintf( buf + rlen,
- "%2d: cs:%s st:%s/%s ld:%s\n"
+ "%2d: cs:%s st:%s/%s ds:%s/%s\n"
" ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
"lo:%d pe:%d ua:%d ap:%d\n",
i, sn,
- nodestate_to_name(drbd_conf[i].state),
- nodestate_to_name(drbd_conf[i].o_state),
- (drbd_conf[i].gen_cnt[Flags]
- & MDF_Consistent) ? "Consistent" : "Inconsistent",
- // FIXME partner consistent?
+ nodestate_to_name(drbd_conf[i].state.s.role),
+ nodestate_to_name(drbd_conf[i].state.s.peer),
+ diskstate_to_name(drbd_conf[i].state.s.disk),
+ diskstate_to_name(drbd_conf[i].state.s.pedi),
drbd_conf[i].send_cnt/2,
drbd_conf[i].recv_cnt/2,
drbd_conf[i].writ_cnt/2,
@@ -243,8 +226,8 @@
atomic_read(&drbd_conf[i].ap_bio_cnt)
);
- if ( drbd_conf[i].cstate == SyncSource ||
- drbd_conf[i].cstate == SyncTarget ) {
+ if ( drbd_conf[i].state.s.conn == SyncSource ||
+ drbd_conf[i].state.s.conn == SyncTarget ) {
rlen += drbd_syncer_progress(drbd_conf+i,buf+rlen);
}
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_receiver.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -555,7 +555,7 @@
set_fs(oldfs);
if(rv != size) {
- set_cstate(mdev,BrokenPipe);
+ drbd_force_state(mdev,NS(conn,BrokenPipe));
drbd_thread_restart_nowait(&mdev->receiver);
}
@@ -606,7 +606,7 @@
if (err) {
ERR("Unable to bind (%d)\n", err);
sock_release(sock2);
- set_cstate(mdev,Unconnected);
+ drbd_force_state(mdev,NS(conn,Unconnected));
return 0;
}
@@ -622,10 +622,10 @@
{
struct socket *sock,*msock;
- D_ASSERT(mdev->cstate!=Unconfigured);
+ D_ASSERT(mdev->state.s.conn > Unconfigured);
D_ASSERT(!mdev->data.socket);
- set_cstate(mdev,WFConnection);
+ if(!drbd_request_state(mdev,NS(conn,WFConnection))) return 0;
while(1) {
sock=drbd_try_connect(mdev);
@@ -649,7 +649,7 @@
sock_release(sock);
}
}
- if(mdev->cstate==Unconnected) return 0;
+ if(mdev->state.s.conn == Unconnected) return 0;
if(signal_pending(current)) {
flush_signals(current);
smp_rmb();
@@ -691,7 +691,7 @@
mdev->meta.socket = msock;
mdev->last_received = jiffies;
- set_cstate(mdev,WFReportParams);
+ if(!drbd_request_state(mdev,NS(conn,WFReportParams))) return 0;
D_ASSERT(mdev->asender.task == NULL);
if (!drbd_do_handshake(mdev)) {
@@ -740,7 +740,7 @@
int epoch_size;
Drbd_Barrier_Packet *p = (Drbd_Barrier_Packet*)h;
- ERR_IF(mdev->state != Secondary) return FALSE;
+ ERR_IF(mdev->state.s.role != Secondary) return FALSE;
ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
rv = drbd_recv(mdev, h->payload, h->length);
@@ -842,8 +842,8 @@
drbd_rs_complete_io(mdev,sector); // before set_in_sync() !
if (likely( drbd_bio_uptodate(&e->private_bio) )) {
- ok = !test_bit(DISKLESS,&mdev->flags) &&
- !test_bit(PARTNER_DISKLESS,&mdev->flags);
+ ok = mdev->state.s.disk >= Inconsistent &&
+ mdev->state.s.pedi >= Inconsistent;
if (likely( ok )) {
drbd_set_in_sync(mdev, sector, drbd_ee_get_size(e));
/* THINK maybe don't send ack either
@@ -1161,19 +1161,23 @@
mdev->sync_conf.skip = be32_to_cpu(p->skip);
drbd_alter_sg(mdev, be32_to_cpu(p->group));
- if ( (mdev->cstate == SkippedSyncS || mdev->cstate == SkippedSyncT)
- && !mdev->sync_conf.skip )
- {
- set_cstate(mdev,WFReportParams);
+ if ( (mdev->state.s.conn == SkippedSyncS ||
+ mdev->state.s.conn == SkippedSyncT)
+ && !mdev->sync_conf.skip ) {
+ drbd_request_state(mdev,NS(conn,WFReportParams));
ok = drbd_send_param(mdev,0);
}
return ok;
}
-STATIC int drbd_sync_handshake(drbd_dev *mdev, Drbd_Parameter_Packet *p)
+/* drbd_sync_handshake() returns the new conn state on success, or
+ conn_mask (-1) on failure.
+ */
+STATIC drbd_conns_t drbd_sync_handshake(drbd_dev *mdev, Drbd_Parameter_Packet *p)
{
int have_good,sync;
+ drbd_conns_t rv = conn_mask;
have_good = drbd_md_compare(mdev,p);
@@ -1190,9 +1194,9 @@
* for now: just go StandAlone.
*/
ALERT("Split-Brain detected, dropping connection!\n");
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
- return FALSE;
+ return conn_mask;
}
sync=0;
} else {
@@ -1206,39 +1210,35 @@
/* doh. I cannot become SyncSource when I am inconsistent!
*/
ERR("I shall become SyncSource, but I am inconsistent!\n");
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
- return FALSE;
+ return conn_mask;
}
if (have_good < 0 &&
!(be32_to_cpu(p->gen_cnt[Flags]) & MDF_Consistent) ) {
/* doh. Peer cannot become SyncSource when inconsistent
*/
ERR("I shall become SyncTarget, but Peer is inconsistent!\n");
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
- return FALSE;
+ return conn_mask;
}
if ( mdev->sync_conf.skip && sync ) {
- if (have_good == 1)
- set_cstate(mdev,SkippedSyncS);
- else // have_good == -1
- set_cstate(mdev,SkippedSyncT);
- return TRUE;
+ return have_good == 1 ? SkippedSyncS : SkippedSyncT ;
}
if( sync ) {
if(have_good == 1) {
D_ASSERT(drbd_md_test_flag(mdev,MDF_Consistent));
- set_cstate(mdev,WFBitMapS);
+ rv = WFBitMapS;
wait_event(mdev->cstate_wait,
atomic_read(&mdev->ap_bio_cnt)==0);
drbd_bm_lock(mdev); // {
drbd_send_bitmap(mdev);
drbd_bm_unlock(mdev); // }
} else { // have_good == -1
- if ( (mdev->state == Primary) &&
+ if ( (mdev->state.s.role == Primary) &&
drbd_md_test_flag(mdev,MDF_Consistent) ) {
/* FIXME
* allow Primary become SyncTarget if it was
@@ -1248,15 +1248,15 @@
*/
ERR("Current Primary shall become sync TARGET!"
" Aborting to prevent data corruption.\n");
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
- return FALSE;
+ return conn_mask;
}
drbd_md_clear_flag(mdev,MDF_Consistent);
- set_cstate(mdev,WFBitMapT);
+ rv = WFBitMapT;
}
} else {
- set_cstate(mdev,Connected);
+ rv = Connected;
drbd_bm_lock(mdev); // {
if(drbd_bm_total_weight(mdev)) {
if (drbd_md_test_flag(mdev,MDF_Consistent)) {
@@ -1283,19 +1283,21 @@
mdev->gen_cnt[i]=be32_to_cpu(p->gen_cnt[i]);
}
}
- return TRUE;
+ return rv;
}
STATIC int receive_param(drbd_dev *mdev, Drbd_Header *h)
{
Drbd_Parameter_Packet *p = (Drbd_Parameter_Packet*)h;
- int consider_sync;
- int oo_state;
+ drbd_conns_t nconn;
+ drbd_disks_t npedi;
+ drbd_state_t ns;
+ int consider_sync,rv;
sector_t p_size;
if (h->length != (sizeof(*p)-sizeof(*h))) {
ERR("Incompatible packet size of Parameter packet!\n");
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return FALSE;
}
@@ -1306,7 +1308,7 @@
if (p->magic != BE_DRBD_MAGIC) {
ERR("invalid Parameter_Packet magic! Protocol version: me %d, peer %d\n",
PRO_VERSION, be32_to_cpu(p->version));
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return FALSE;
}
@@ -1314,26 +1316,11 @@
if(be32_to_cpu(p->version)!=PRO_VERSION) {
ERR("incompatible releases! Protocol version: me %d, peer %d\n",
PRO_VERSION, be32_to_cpu(p->version));
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return FALSE;
}
- oo_state = be32_to_cpu(p->state);
- if (oo_state != Primary && oo_state != Secondary) {
- ERR("unexpected peer state: 0x%x\n", oo_state);
- set_cstate(mdev,StandAlone);
- drbd_thread_stop_nowait(&mdev->receiver);
- return FALSE;
- }
-
- if(be32_to_cpu(p->state) == Primary && mdev->state == Primary ) {
- ERR("incompatible states (both Primary!)\n");
- set_cstate(mdev,StandAlone);
- drbd_thread_stop_nowait(&mdev->receiver);
- return FALSE;
- }
-
if(be32_to_cpu(p->protocol)!=mdev->conf.wire_protocol) {
int peer_proto = be32_to_cpu(p->protocol);
if (DRBD_PROT_A <= peer_proto && peer_proto <= DRBD_PROT_C) {
@@ -1347,18 +1334,18 @@
'A'-1+mdev->conf.wire_protocol,
peer_proto);
}
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return FALSE;
}
p_size=be64_to_cpu(p->p_size);
- if(p_size == 0 && test_bit(DISKLESS,&mdev->flags)) {
+ if(p_size == 0 && mdev->state.s.disk == Diskless ) {
/* FIXME maybe allow connection,
* but refuse to become primary? */
ERR("some backing storage is needed\n");
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
drbd_thread_stop_nowait(&mdev->receiver);
return FALSE;
}
@@ -1374,7 +1361,7 @@
* right, and comment them!
*/
- consider_sync = (mdev->cstate == WFReportParams);
+ consider_sync = ((nconn=mdev->state.s.conn) == WFReportParams);
if(drbd_determin_dev_size(mdev)) consider_sync=0;
drbd_bm_unlock(mdev); // }
@@ -1401,72 +1388,41 @@
(unsigned long)mdev->lo_usize);
}
- if(!p_size) {
- /* no point in trying to sync a diskless peer: */
- consider_sync = 0;
- if (!test_and_set_bit(PARTNER_DISKLESS, &mdev->flags)) {
- /* if we got here, we *do* have a disk.
- * but it may be inconsistent...
- * anyways, record that next time we need a full sync.
- */
- clear_bit(PARTNER_CONSISTENT, &mdev->flags);
- drbd_md_set_flag(mdev,MDF_FullSync);
- drbd_md_write(mdev);
- /* actually we'd need to bm_fill_bm(,-1); drbd_write_bm(mdev);
- * but this is not necessary _now_.
- * we have the MDF_FullSync bit on disk.
- * on the next _drbd_send_bitmap this will be done.
- */
- WARN("PARTNER DISKLESS\n");
- mdev->rs_total = 0;
+
+ if(p_size ) {
+ npedi = Inconsistent;
+ if (be32_to_cpu(p->gen_cnt[Flags]) & MDF_Consistent) {
+ npedi = Consistent;
}
- if(mdev->cstate >= Connected ) {
- if(mdev->state == Primary) tl_clear(mdev);
- if(mdev->state == Primary ||
- be32_to_cpu(p->state) == Primary ) {
- drbd_md_inc(mdev,ConnectedCnt);
- }
- }
- if(mdev->cstate > Connected ) {
- WARN("Resync aborted.\n");
- set_cstate(mdev,Connected);
- }
} else {
- if (test_and_clear_bit(PARTNER_DISKLESS, &mdev->flags)) {
- WARN("Partner no longer diskless\n");
- D_ASSERT(consider_sync);
- }
+ npedi = Diskless;
}
- if (be32_to_cpu(p->gen_cnt[Flags]) & MDF_Consistent) {
- set_bit(PARTNER_CONSISTENT, &mdev->flags);
- } else {
- clear_bit(PARTNER_CONSISTENT, &mdev->flags);
- }
-
- if (mdev->cstate == WFReportParams) {
+ if (mdev->state.s.conn == WFReportParams) {
INFO("Connection established.\n");
}
+ nconn=Connected;
if (consider_sync) {
- if (!drbd_sync_handshake(mdev,p)) return FALSE;
+ if ((nconn=drbd_sync_handshake(mdev,p))==conn_mask)
+ return FALSE;
}
- if (mdev->cstate == WFReportParams) set_cstate(mdev,Connected);
+ spin_lock_irq(&mdev->req_lock);
+ ns.i = mdev->state.i;
+ ns.s.conn = nconn;
+ ns.s.peer = be32_to_cpu(p->state);
+ ns.s.pedi = npedi;
+ rv = _drbd_set_state(mdev,ns,0);
+ spin_unlock_irq(&mdev->req_lock);
- oo_state = mdev->o_state;
- mdev->o_state = be32_to_cpu(p->state);
- if(oo_state == Secondary && mdev->o_state == Primary) {
- drbd_md_inc(mdev,ConnectedCnt);
+ if(!rv) {
+ drbd_force_state(mdev,NS(conn,StandAlone));
+ drbd_thread_stop_nowait(&mdev->receiver);
+ return FALSE;
}
- if (oo_state != mdev->o_state) {
- INFO( "%s/%s --> %s/%s\n",
- nodestate_to_name(mdev->state),
- nodestate_to_name(oo_state),
- nodestate_to_name(mdev->state),
- nodestate_to_name(mdev->o_state) );
- /* FIXME assertion for (gencounts do not diverge) */
- }
+
+ /* FIXME assertion for (gencounts do not diverge) */
drbd_md_write(mdev); // update connected indicator, la_size, ...
return TRUE;
@@ -1508,15 +1464,15 @@
D_ASSERT(h->command == ReportBitMap);
}
- if (mdev->cstate == WFBitMapS) {
+ if (mdev->state.s.conn == WFBitMapS) {
drbd_start_resync(mdev,SyncSource);
- } else if (mdev->cstate == WFBitMapT) {
+ } else if (mdev->state.s.conn == WFBitMapT) {
ok = drbd_send_bitmap(mdev);
if (!ok) goto out;
drbd_start_resync(mdev,SyncTarget); // XXX cannot fail ???
} else {
ERR("unexpected cstate (%s) in receive_bitmap\n",
- cstate_to_name(mdev->cstate));
+ cstate_to_name(mdev->state.s.conn));
}
// We just started resync. Now we can be sure that local disk IO is okay.
@@ -1528,8 +1484,8 @@
* FIXME this should only be D_ASSERT here.
* *doing* it here masks a logic bug elsewhere, I think.
*/
- D_ASSERT(!test_bit(PARTNER_DISKLESS,&mdev->flags));
- D_ASSERT(!test_bit(DISKLESS,&mdev->flags));
+ D_ASSERT(mdev->state.s.disk >= Inconsistent);
+ D_ASSERT(mdev->state.s.pedi >= Inconsistent);
// EXPLAIN:
clear_bit(MD_IO_ALLOWED,&mdev->flags);
@@ -1593,13 +1549,6 @@
{
ERR_IF(!mdev->bitmap) return FALSE;
- /* THINK
- * otherwise this does not make much sense, no?
- * and some other assertion maybe about cstate...
- */
- ERR_IF(mdev->state != Secondary || mdev->cstate != Connected)
- return FALSE;
-
drbd_bm_lock(mdev);
drbd_bm_set_all(mdev);
drbd_bm_write(mdev);
@@ -1621,7 +1570,7 @@
STATIC int receive_UnplugRemote(drbd_dev *mdev, Drbd_Header *h)
{
- if (!test_bit(DISKLESS,&mdev->flags)) drbd_kick_lo(mdev);
+ if (mdev->state.s.disk >= Inconsistent) drbd_kick_lo(mdev);
return TRUE; // cannot fail.
}
@@ -1673,7 +1622,7 @@
header->command, header->length);
break;
}
- if (mdev->cstate == WFReportParams && header->command != ReportParams) {
+ if (mdev->state.s.conn == WFReportParams && header->command != ReportParams) {
ERR("received %s packet while WFReportParams!?\n",
cmdname(header->command));
}
@@ -1688,8 +1637,7 @@
STATIC void drbd_disconnect(drbd_dev *mdev)
{
- D_ASSERT(mdev->cstate < Connected);
- mdev->o_state = Unknown;
+ D_ASSERT(mdev->state.s.conn < Connected);
/* in case we have been syncing, and then we drop the connection,
* we need to "w_resume_next_sg", which we try to achieve by
@@ -1751,10 +1699,6 @@
wait_event( mdev->cstate_wait, atomic_read(&mdev->ap_pending_cnt)==0 );
D_ASSERT(mdev->oldest_barrier->n_req == 0);
- // both
- clear_bit(PARTNER_CONSISTENT, &mdev->flags);
- clear_bit(PARTNER_DISKLESS,&mdev->flags);
-
D_ASSERT(mdev->ee_in_use == 0);
D_ASSERT(list_empty(&mdev->read_ee)); // done by termination of worker
D_ASSERT(list_empty(&mdev->active_ee)); // done here
@@ -1788,27 +1732,15 @@
wake_up(&mdev->cstate_wait);
- if ( mdev->state == Primary &&
- ( test_bit(DISKLESS,&mdev->flags)
- || !drbd_md_test_flag(mdev,MDF_Consistent) ) ) {
- drbd_panic("Sorry, I have no access to good data anymore.\n");
- }
-
if (get_t_state(&mdev->receiver) == Exiting) {
- if (test_bit(DISKLESS,&mdev->flags)) {
- // Secondary
- set_cstate(mdev,Unconfigured);
- drbd_mdev_cleanup(mdev);
- } else {
- set_cstate(mdev,StandAlone);
- drbd_thread_start(&mdev->worker);
- }
+ drbd_force_state(mdev,NS(conn,StandAlone));
+ drbd_thread_start(&mdev->worker);
} else {
- set_cstate(mdev,Unconnected);
+ drbd_force_state(mdev,NS(conn,Unconnected));
drbd_thread_start(&mdev->worker);
}
- if (mdev->state == Primary) {
+ if (mdev->state.s.role == Primary) {
if(!test_bit(DO_NOT_INC_CONCNT,&mdev->flags))
drbd_md_inc(mdev,ConnectedCnt);
drbd_md_write(mdev);
@@ -1926,7 +1858,7 @@
* drbd_disconnect should set cstate properly...
*/
drbd_disconnect(mdev);
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
break;
}
if (get_t_state(thi) == Exiting) break;
@@ -1934,7 +1866,7 @@
drbd_disconnect(mdev);
if (get_t_state(thi) == Exiting) break;
if(mdev->conf.on_disconnect == DropNetConf) {
- set_cstate(mdev,StandAlone);
+ drbd_force_state(mdev,NS(conn,StandAlone));
break;
}
else {
@@ -1977,7 +1909,7 @@
int blksize = be32_to_cpu(p->blksize);
smp_rmb();
- if(likely(!test_bit(PARTNER_DISKLESS,&mdev->flags))) {
+ if(likely(mdev->state.s.pedi >= Inconsistent )) {
// test_bit(PARTNER_DISKLESS,&mdev->flags)
// This happens if one a few IO requests on the peer
// failed, and some subsequest completed sucessfull
@@ -2073,7 +2005,7 @@
Drbd_BarrierAck_Packet *p = (Drbd_BarrierAck_Packet*)h;
smp_rmb();
- if(unlikely(test_bit(PARTNER_DISKLESS,&mdev->flags))) return TRUE;
+ if(unlikely(mdev->state.s.pedi <= Diskless)) return TRUE;
tl_release(mdev,p->barrier,be32_to_cpu(p->set_size));
dec_ap_pending(mdev);
@@ -2199,8 +2131,8 @@
if(0) {
err:
clear_bit(SIGNAL_ASENDER, &mdev->flags);
- if (mdev->cstate >= Connected)
- set_cstate(mdev,NetworkFailure);
+ if (mdev->state.s.conn >= Connected)
+ drbd_force_state(mdev,NS(conn,NetworkFailure));
drbd_thread_restart_nowait(&mdev->receiver);
}
Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_req.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -178,7 +178,7 @@
* not always true, e.g. someone trying to mount on Secondary
* maybe error out immediately here?
*/
- D_ASSERT(mdev->state == Primary);
+ D_ASSERT(mdev->state.s.role == Primary);
/*
* Paranoia: we might have been primary, but sync target, or
@@ -189,13 +189,11 @@
* to serialize state changes, this is racy, since we may lose
* the connection *after* we test for the cstate.
*/
- if ( ( test_bit(DISKLESS,&mdev->flags)
- || !drbd_md_test_flag(mdev,MDF_Consistent)
- ) && mdev->cstate < Connected )
- {
+ if ( mdev->state.s.disk <= Inconsistent &&
+ mdev->state.s.conn < Connected) {
ERR("Sorry, I have no access to good data anymore.\n");
/*
- FIXME suspend, loop waiting on cstate wait? panic?
+ FIXME suspend, loop waiting on cstate wait? panic?
*/
drbd_bio_IO_error(bio);
return 0;
@@ -226,8 +224,8 @@
// down_read(mdev->device_lock);
wait_event( mdev->cstate_wait,
- (volatile int)(mdev->cstate < WFBitMapS ||
- mdev->cstate > WFBitMapT) );
+ (volatile int)(mdev->state.s.conn < WFBitMapS ||
+ mdev->state.s.conn > WFBitMapT) );
local = inc_local(mdev);
if (rw == READ || rw == READA) {
@@ -257,7 +255,7 @@
dec_local(mdev);
}
}
- remote = !local && test_bit(PARTNER_CONSISTENT, &mdev->flags);
+ remote = !local && mdev->state.s.pedi >= Consistent;
} else {
remote = 1;
}
@@ -270,7 +268,7 @@
* or make this configurable...
* if network is slow, READA won't do any good.
*/
- if (rw == READA && !test_bit(DISKLESS,&mdev->flags) && !local) {
+ if (rw == READA && mdev->state.s.disk >= Inconsistent && !local) {
drbd_bio_IO_error(bio);
return 0;
}
@@ -278,8 +276,7 @@
if (rw == WRITE && local)
drbd_al_begin_io(mdev, sector);
- remote = remote && (mdev->cstate >= Connected)
- && !test_bit(PARTNER_DISKLESS,&mdev->flags);
+ remote = remote && (mdev->state.s.pedi >= Inconsistent);
if (!(local || remote)) {
ERR("IO ERROR: neither local nor remote disk\n");
@@ -308,8 +305,8 @@
inc_ap_pending(mdev);
if (rw == WRITE) {
if (!drbd_send_dblock(mdev,req)) {
- if (mdev->cstate >= Connected)
- set_cstate(mdev,NetworkFailure);
+ if (mdev->state.s.conn >= Connected)
+ drbd_force_state(mdev,NS(conn,NetworkFailure));
dec_ap_pending(mdev);
drbd_thread_restart_nowait(&mdev->receiver);
} else if(mdev->conf.wire_protocol == DRBD_PROT_A) {
@@ -352,7 +349,7 @@
{
unsigned int s_enr,e_enr;
struct Drbd_Conf* mdev = (drbd_dev*) q->queuedata;
- if (mdev->cstate < StandAlone) {
+ if (mdev->state.s.disk < Inconsistent) {
drbd_bio_IO_error(bio);
return 0;
}
Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_strings.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -1,4 +1,28 @@
-static const char *conn_s_names[] = {
+/*
+ drbd.h
+ Kernel module for 2.4.x/2.6.x Kernels
+
+ This file is part of drbd by Philipp Reisner.
+
+ drbd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ drbd is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with drbd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/drbd.h>
+
+const char *drbd_conn_s_names[] = {
[Unconfigured] = "Unconfigured",
[StandAlone] = "StandAlone",
[Unconnected] = "Unconnected",
@@ -18,13 +42,14 @@
[PausedSyncT] = "PausedSyncT",
};
-static const char *role_s_names[] = {
+const char *drbd_role_s_names[] = {
[Primary] = "Primary",
[Secondary] = "Secondary",
[Unknown] = "Unknown"
};
-static const char *disk_s_names[] = {
+const char *drbd_disk_s_names[] = {
+ [DUnknown] = "DUnknown",
[Diskless] = "Diskless",
[Failed] = "Failed",
[Inconsistent] = "Inconsistent",
Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/drbd_worker.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -228,8 +228,8 @@
smp_rmb();
if ( cancel ||
- mdev->cstate < Connected ||
- !test_bit(PARTNER_CONSISTENT,&mdev->flags) ) {
+ mdev->state.s.conn < Connected ||
+ mdev->state.s.pedi < Consistent ) {
drbd_panic("WE ARE LOST. Local IO failure, no peer.\n");
// does not make much sense, but anyways...
@@ -312,13 +312,13 @@
if(unlikely(cancel)) return 1;
/* FIXME THINK what about w_resume_next_sg ?? */
- if(unlikely(mdev->cstate < Connected)) {
+ if(unlikely(mdev->state.s.conn < Connected)) {
ERR("Confused in w_make_resync_request()! cstate < Connected");
return 0;
}
- if (mdev->cstate != SyncTarget) {
- ERR("%s in w_make_resync_request\n", cstate_to_name(mdev->cstate));
+ if (mdev->state.s.conn != SyncTarget) {
+ ERR("%s in w_make_resync_request\n", cstate_to_name(mdev->state.s.conn));
}
number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ);
@@ -394,25 +394,18 @@
INFO("Resync done (total %lu sec; paused %lu sec; %lu K/sec)\n",
dt + mdev->rs_paused, mdev->rs_paused, dbdt);
- if (mdev->cstate == SyncTarget || mdev->cstate == PausedSyncT) {
- drbd_md_set_flag(mdev,MDF_Consistent);
- ERR_IF(drbd_md_test_flag(mdev,MDF_FullSync))
- drbd_md_clear_flag(mdev,MDF_FullSync);
- drbd_md_write(mdev);
- } else if (mdev->cstate == SyncSource || mdev->cstate == PausedSyncS) {
- set_bit(PARTNER_CONSISTENT, &mdev->flags);
- } else {
- ERR("unexpected cstate (%s) in drbd_resync_finished\n",
- cstate_to_name(mdev->cstate));
- }
-
// assert that all bit-map parts are cleared.
D_ASSERT(list_empty(&mdev->resync->lru));
D_ASSERT(drbd_bm_total_weight(mdev) == 0);
mdev->rs_total = 0;
mdev->rs_paused = 0;
- set_cstate(mdev,Connected);
+ drbd_request_state(mdev,NS3(conn,Connected,
+ disk,Consistent,
+ pedi,Consistent));
+
+ drbd_md_write(mdev);
+
/* FIXME
* _queueing_ of w_resume_next_sg() gets _scheduled_ here.
* maybe rather _do_ it right here instead? */
@@ -472,7 +465,7 @@
drbd_rs_complete_io(mdev,drbd_ee_get_sector(e));
if(likely(drbd_bio_uptodate(&e->private_bio))) {
- if (likely( !test_bit(PARTNER_DISKLESS,&mdev->flags) )) {
+ if (likely( mdev->state.s.pedi >= Inconsistent )) {
inc_rs_pending(mdev);
ok=drbd_send_block(mdev, RSDataReply, e);
} else {
@@ -545,16 +538,16 @@
STATIC void _drbd_rs_resume(drbd_dev *mdev)
{
- Drbd_CState ns;
+ drbd_conns_t ncs;
- ns = mdev->cstate - (PausedSyncS - SyncSource);
- D_ASSERT(ns == SyncSource || ns == SyncTarget);
+ ncs = mdev->state.s.conn - (PausedSyncS - SyncSource);
+ D_ASSERT(ncs == SyncSource || ncs == SyncTarget);
INFO("Syncer continues.\n");
mdev->rs_paused += (long)jiffies-(long)mdev->rs_mark_time;
- _set_cstate(mdev,ns);
+ _drbd_set_state(mdev,_NS(conn,ncs),1);
- if(mdev->cstate == SyncTarget) {
+ if(mdev->state.s.conn == SyncTarget) {
ERR_IF(test_bit(STOP_SYNC_TIMER,&mdev->flags)) {
unsigned long rs_left = drbd_bm_total_weight(mdev);
clear_bit(STOP_SYNC_TIMER,&mdev->flags);
@@ -573,16 +566,17 @@
STATIC void _drbd_rs_pause(drbd_dev *mdev)
{
- Drbd_CState ns;
+ drbd_conns_t ncs;
- D_ASSERT(mdev->cstate == SyncSource || mdev->cstate == SyncTarget);
- ns = mdev->cstate + (PausedSyncS - SyncSource);
+ D_ASSERT(mdev->state.s.conn == SyncSource || mdev->state.s.conn == SyncTarget);
+ ncs = mdev->state.s.conn + (PausedSyncS - SyncSource);
- if(mdev->cstate == SyncTarget) set_bit(STOP_SYNC_TIMER,&mdev->flags);
+ if(mdev->state.s.conn == SyncTarget) set_bit(STOP_SYNC_TIMER,&mdev->flags);
mdev->rs_mark_time = jiffies;
// mdev->rs_mark_left = drbd_bm_total_weight(mdev); // I don't care...
- _set_cstate(mdev,ns);
+ _drbd_set_state(mdev,_NS(conn,ncs),1);
+
INFO("Syncer waits for sync group.\n");
}
@@ -594,8 +588,8 @@
for (i=0; i < minor_count; i++) {
odev = drbd_conf + i;
if ( odev->sync_conf.group > mdev->sync_conf.group
- && ( odev->cstate == SyncSource ||
- odev->cstate == SyncTarget ) ) {
+ && ( odev->state.s.conn == SyncSource ||
+ odev->state.s.conn == SyncTarget ) ) {
_drbd_rs_pause(odev);
rv = 1;
}
@@ -612,8 +606,8 @@
for (i=0; i < minor_count; i++) {
odev = drbd_conf + i;
if ( odev->sync_conf.group < mdev->sync_conf.group
- && ( odev->cstate == SyncSource ||
- odev->cstate == SyncTarget ) ) {
+ && ( odev->state.s.conn == SyncSource ||
+ odev->state.s.conn == SyncTarget ) ) {
rv = 1;
}
}
@@ -629,8 +623,8 @@
for (i=0; i < minor_count; i++) {
odev = drbd_conf + i;
if ( odev->sync_conf.group < mdev->sync_conf.group
- && ( odev->cstate == PausedSyncS ||
- odev->cstate == PausedSyncT ) ) {
+ && ( odev->state.s.conn == PausedSyncS ||
+ odev->state.s.conn == PausedSyncT ) ) {
_drbd_rs_resume(odev);
rv = 1;
}
@@ -651,8 +645,8 @@
for (i=0; i < minor_count; i++) {
odev = drbd_conf + i;
if ( odev->sync_conf.group == mdev->sync_conf.group
- && ( odev->cstate == SyncSource ||
- odev->cstate == SyncTarget ) ) {
+ && ( odev->state.s.conn == SyncSource ||
+ odev->state.s.conn == SyncTarget ) ) {
goto out; // Sync on an other device in this group
// still runs.
}
@@ -662,7 +656,7 @@
odev = drbd_conf + i;
if ( odev->sync_conf.group > mdev->sync_conf.group
&& odev->sync_conf.group < ng &&
- (odev->cstate==PausedSyncS || odev->cstate==PausedSyncT)){
+ (odev->state.s.conn==PausedSyncS || odev->state.s.conn==PausedSyncT)){
ng = odev->sync_conf.group;
}
}
@@ -670,7 +664,7 @@
for (i=0; i < minor_count; i++) { // resume all devices in next group
odev = drbd_conf + i;
if ( odev->sync_conf.group == ng &&
- (odev->cstate==PausedSyncS || odev->cstate==PausedSyncT)){
+ (odev->state.s.conn==PausedSyncS || odev->state.s.conn==PausedSyncT)){
_drbd_rs_resume(odev);
}
}
@@ -690,15 +684,15 @@
drbd_global_lock();
mdev->sync_conf.group = ng;
- if( ( mdev->cstate == PausedSyncS ||
- mdev->cstate == PausedSyncT ) && ( d < 0 ) ) {
+ if( ( mdev->state.s.conn == PausedSyncS ||
+ mdev->state.s.conn == PausedSyncT ) && ( d < 0 ) ) {
if(_drbd_pause_higher_sg(mdev)) c=1;
else if(!_drbd_lower_sg_running(mdev)) c=1;
if(c) _drbd_rs_resume(mdev);
}
- if( ( mdev->cstate == SyncSource ||
- mdev->cstate == SyncTarget ) && ( d > 0 ) ) {
+ if( ( mdev->state.s.conn == SyncSource ||
+ mdev->state.s.conn == SyncTarget ) && ( d > 0 ) ) {
if(_drbd_resume_lower_sg(mdev)) p=1;
else if(_drbd_lower_sg_running(mdev)) p=1;
if(p) _drbd_rs_pause(mdev);
@@ -706,13 +700,17 @@
drbd_global_unlock();
}
-void drbd_start_resync(drbd_dev *mdev, Drbd_CState side)
+void drbd_start_resync(drbd_dev *mdev, drbd_conns_t side)
{
+ int r=0;
+
if(side == SyncTarget) {
- drbd_md_clear_flag(mdev,MDF_Consistent);
drbd_bm_reset_find(mdev);
+ r = drbd_request_state(mdev,NS2(conn,SyncTarget,
+ disk,Inconsistent));
} else if (side == SyncSource) {
- clear_bit(PARTNER_CONSISTENT, &mdev->flags);
+ r = drbd_request_state(mdev,NS2(conn,SyncSource,
+ pedi,Inconsistent));
/* If we are SyncSource we must be consistent.
* FIXME this should be an assertion only,
* otherwise it masks a logic bug somewhere else...
@@ -721,14 +719,16 @@
// FIXME this is actually a BUG()!
drbd_md_set_flag(mdev,MDF_Consistent);
}
- } else {
- ERR("Usage error in drbd_start_resync! (side == %s)\n",
- cstate_to_name(side));
+ }
+
+ if(r != 1) {
+ ERR("Error in drbd_start_resync! (side == %s)\n",
+ cstate_to_name(side));
return;
}
+
drbd_md_write(mdev);
- set_cstate(mdev,side);
mdev->rs_total =
mdev->rs_mark_left = drbd_bm_total_weight(mdev);
mdev->rs_paused = 0;
@@ -757,15 +757,14 @@
return;
}
- /* FIXME THINK
- * use mdev->cstate (we may already be paused...) or side here ?? */
- if (mdev->cstate == SyncTarget) {
+ if (side == SyncTarget) {
D_ASSERT(!test_bit(STOP_SYNC_TIMER,&mdev->flags));
mod_timer(&mdev->resync_timer,jiffies);
}
drbd_global_lock();
- if (mdev->cstate == SyncTarget || mdev->cstate == SyncSource) {
+ if ( mdev->state.s.conn == SyncTarget ||
+ mdev->state.s.conn == SyncSource ) {
_drbd_pause_higher_sg(mdev);
if(_drbd_lower_sg_running(mdev)) {
_drbd_rs_pause(mdev);
@@ -818,10 +817,10 @@
list_del_init(&w->list);
spin_unlock_irq(&mdev->req_lock);
- if(!w->cb(mdev,w, mdev->cstate < Connected )) {
+ if(!w->cb(mdev,w, mdev->state.s.conn < Connected )) {
//WARN("worker: a callback failed! \n");
- if (mdev->cstate >= Connected)
- set_cstate(mdev,NetworkFailure);
+ if (mdev->state.s.conn >= Connected)
+ drbd_force_state(mdev,NS(conn,NetworkFailure));
drbd_thread_restart_nowait(&mdev->receiver);
}
}
Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/drbd/linux/drbd.h 2004-11-03 15:57:30 UTC (rev 1624)
@@ -52,6 +52,11 @@
divisible by 8.
*/
+/* defined in drbd_strings.c */
+extern const char *drbd_conn_s_names[];
+extern const char *drbd_role_s_names[];
+extern const char *drbd_disk_s_names[];
+
#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
16 for IP, 16 for IPX,
24 for IPv6,
@@ -163,10 +168,11 @@
Unknown=0,
Primary=1, // role
Secondary=2, // role
+ role_mask=3,
Human=4, // flag for set_state
TimeoutExpired=8, // flag for set_state
DontBlameDrbd=16 // flag for set_state
-} Drbd_State;
+} drbd_role_t;
/* The order of these constants is important.
* The lower ones (<WFReportParams) indicate
@@ -195,8 +201,33 @@
SyncTarget, // state must be the same for source and target. (+2)
PausedSyncS, // see _drbd_rs_resume() and _drbd_rs_pause()
PausedSyncT, // is sync target, but higher priority groups first
-} Drbd_CState;
+ conn_mask=31
+} drbd_conns_t;
+typedef enum {
+ DUnknown,
+ Diskless,
+ Failed, /* Becomes Diskless as soon as we told it the peer */
+ Inconsistent,
+ Outdated,
+ Consistent, /* Might be outdated, might be UpToDate ... */
+ UpToDate,
+ disk_mask=7
+} drbd_disks_t;
+
+typedef union {
+ struct {
+ unsigned role : 2 ; // 3/3 primary/secondary/unknown
+ unsigned peer : 2 ; // 3/3 primary/secondary/unknown
+ unsigned conn : 5 ; // 17/32 cstates
+ unsigned disk : 3 ; // 7/7 from DUnknown to UpToDate
+ unsigned pedi : 3 ; // 7/7 from DUnknown to UpToDate
+ unsigned mult : 1 ; // 2/2 multiple primaries allowed
+ unsigned _pad : 16; // 0 unused
+ } s;
+ unsigned int i;
+} drbd_state_t;
+
#ifndef BDEVNAME_SIZE
# define BDEVNAME_SIZE 32
#endif
@@ -213,9 +244,7 @@
OUT int meta_device_major;
OUT int meta_device_minor;
OUT int meta_index;
- OUT Drbd_CState cstate;
- OUT Drbd_State state;
- OUT Drbd_State peer_state;
+ OUT drbd_state_t state;
int _pad;
};
@@ -227,7 +256,7 @@
*/
#define DRBD_IOCTL_LETTER 'D'
#define DRBD_IOCTL_GET_VERSION _IOR( DRBD_IOCTL_LETTER, 0x00, int )
-#define DRBD_IOCTL_SET_STATE _IOW( DRBD_IOCTL_LETTER, 0x02, Drbd_State )
+#define DRBD_IOCTL_SET_STATE _IOW( DRBD_IOCTL_LETTER, 0x02, drbd_role_t )
#define DRBD_IOCTL_SET_DISK_CONFIG _IOW( DRBD_IOCTL_LETTER, 0x06, struct ioctl_disk_config )
#define DRBD_IOCTL_SET_NET_CONFIG _IOW( DRBD_IOCTL_LETTER, 0x07, struct ioctl_net_config )
#define DRBD_IOCTL_UNCONFIG_NET _IO ( DRBD_IOCTL_LETTER, 0x08 )
@@ -239,7 +268,7 @@
#define DRBD_IOCTL_WAIT_CONNECT _IOR( DRBD_IOCTL_LETTER, 0x11, struct ioctl_wait )
#define DRBD_IOCTL_WAIT_SYNC _IOR( DRBD_IOCTL_LETTER, 0x12, struct ioctl_wait )
#define DRBD_IOCTL_UNCONFIG_DISK _IO ( DRBD_IOCTL_LETTER, 0x13 )
-#define DRBD_IOCTL_SET_STATE_FLAGS _IOW( DRBD_IOCTL_LETTER, 0x14, Drbd_State )
+#define DRBD_IOCTL_SET_STATE_FLAGS _IOW( DRBD_IOCTL_LETTER, 0x14, drbd_role_t )
#endif
Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c 2004-11-02 22:12:08 UTC (rev 1623)
+++ trunk/user/drbdsetup.c 2004-11-03 15:57:30 UTC (rev 1624)
@@ -670,7 +670,7 @@
-int set_state(int drbd_fd,Drbd_State state)
+int set_state(int drbd_fd,drbd_role_t state)
{
int err;
err=ioctl(drbd_fd,DRBD_IOCTL_SET_STATE,state);
@@ -703,7 +703,7 @@
int cmd_primary(int drbd_fd,char** argv,int argc,struct option *options)
{
- Drbd_State newstate=Primary;
+ drbd_role_t newstate=Primary;
if(argc > 0)
{
@@ -756,7 +756,7 @@
int cmd_on_primary(int drbd_fd,char** argv,int argc,struct option *options)
{
int err;
- Drbd_State flags=0;
+ drbd_role_t flags=0;
if(argc > 0)
{
@@ -1168,72 +1168,78 @@
return 20;
}
- if( cn.cstate < StandAlone )
+ if( cn.state.s.conn == StandAlone && cn.state.s.disk == Diskless)
{
printf("Not configured\n");
return 0;
}
- printf("Lower device: %02d:%02d (%s)\n",
- cn.lower_device_major,
- cn.lower_device_minor,
- check_dev_name(cn.lower_device_name,cn.lower_device_major,
- cn.lower_device_minor));
- if( cn.lower_device_major == cn.meta_device_major &&
- cn.lower_device_minor == cn.meta_device_minor ) {
- printf("Meta device: internal\n");
- } else {
- printf("Meta device: %02d:%02d (%s)\n",
- cn.meta_device_major,
- cn.meta_device_minor,
- check_dev_name(cn.meta_device_name,cn.meta_device_major,
- cn.meta_device_minor));
- printf("Meta index: %d\n",cn.meta_index);
- }
+ if( cn.state.s.disk > Diskless)
+ {
- printf("Disk options:\n");
- if( cn.disk_size_user ) printf(" size = %lu KB\n",
- (unsigned long)cn.disk_size_user);
- if( cn.on_io_error != DEF_ON_IO_ERROR) {
- printf(" on-io-error = %s\n",eh_names[cn.on_io_error]);
- }
+ printf("Lower device: %02d:%02d (%s)\n",
+ cn.lower_device_major,
+ cn.lower_device_minor,
+ check_dev_name(cn.lower_device_name,cn.lower_device_major,
+ cn.lower_device_minor));
+ if( cn.lower_device_major == cn.meta_device_major &&
+ cn.lower_device_minor == cn.meta_device_minor ) {
+ printf("Meta device: internal\n");
+ } else {
+ printf("Meta device: %02d:%02d (%s)\n",
+ cn.meta_device_major,
+ cn.meta_device_minor,
+ check_dev_name(cn.meta_device_name,cn.meta_device_major,
+ cn.meta_device_minor));
+ printf("Meta index: %d\n",cn.meta_index);
+ }
- if( cn.cstate < Unconnected ) return 0;
+ printf("Disk options:\n");
+ if( cn.disk_size_user ) printf(" size = %lu KB\n",
+ (unsigned long)cn.disk_size_user);
+ if( cn.on_io_error != DEF_ON_IO_ERROR) {
+ printf(" on-io-error = %s\n",eh_names[cn.on_io_error]);
+ }
- my_addr = (struct sockaddr_in *)cn.nconf.my_addr;
- other_addr = (struct sockaddr_in *)cn.nconf.other_addr;
- printf("Local address: %s:%d\n",
- inet_ntoa(my_addr->sin_addr),
- ntohs(my_addr->sin_port));
- printf("Remote address: %s:%d\n",
- inet_ntoa(other_addr->sin_addr),
- ntohs(other_addr->sin_port));
- printf("Wire protocol: %c\n",'A'-1+cn.nconf.wire_protocol);
- printf("Net options:\n");
- printf(" timeout = %d.%d sec %s\n",cn.nconf.timeout/10,cn.nconf.timeout%10,
- cn.nconf.timeout == DEF_NET_TIMEOUT ? "(default)" : "" );
+ }
+ if( cn.state.s.conn > StandAlone)
+ {
+ my_addr = (struct sockaddr_in *)cn.nconf.my_addr;
+ other_addr = (struct sockaddr_in *)cn.nconf.other_addr;
+ printf("Local address: %s:%d\n",
+ inet_ntoa(my_addr->sin_addr),
+ ntohs(my_addr->sin_port));
+ printf("Remote address: %s:%d\n",
+ inet_ntoa(other_addr->sin_addr),
+ ntohs(other_addr->sin_port));
+ printf("Wire protocol: %c\n",'A'-1+cn.nconf.wire_protocol);
+ printf("Net options:\n");
+ printf(" timeout = %d.%d sec %s\n",cn.nconf.timeout/10,cn.nconf.timeout%10,
+ cn.nconf.timeout == DEF_NET_TIMEOUT ? "(default)" : "" );
+
#define SHOW_I(T,U,M,D) printf(" " T " = %d " U " %s\n", M, M == D ? "(default)" : "")
- SHOW_I("connect-int","sec", cn.nconf.try_connect_int, DEF_NET_TRY_CON_I);
- SHOW_I("ping-int","sec", cn.nconf.ping_int, DEF_NET_PING_I);
- SHOW_I("max-epoch-size","", cn.nconf.max_epoch_size, DEF_MAX_EPOCH_SIZE);
- SHOW_I("max-buffers","", cn.nconf.max_buffers, DEF_MAX_BUFFERS);
- SHOW_I("sndbuf-size","", cn.nconf.sndbuf_size, DEF_SNDBUF_SIZE);
- SHOW_I("ko-count","", cn.nconf.ko_count, DEF_KO_COUNT);
- if( cn.nconf.on_disconnect != DEF_ON_DISCONNECT) {
- printf(" on-disconnect = %s\n",dh_names[cn.nconf.on_disconnect]);
- }
+ SHOW_I("connect-int","sec", cn.nconf.try_connect_int, DEF_NET_TRY_CON_I);
+ SHOW_I("ping-int","sec", cn.nconf.ping_int, DEF_NET_PING_I);
+ SHOW_I("max-epoch-size","", cn.nconf.max_epoch_size, DEF_MAX_EPOCH_SIZE);
+ SHOW_I("max-buffers","", cn.nconf.max_buffers, DEF_MAX_BUFFERS);
+ SHOW_I("sndbuf-size","", cn.nconf.sndbuf_size, DEF_SNDBUF_SIZE);
+ SHOW_I("ko-count","", cn.nconf.ko_count, DEF_KO_COUNT);
+ if( cn.nconf.on_disconnect != DEF_ON_DISCONNECT) {
+ printf(" on-disconnect = %s\n",dh_names[cn.nconf.on_disconnect]);
+ }
- printf("Syncer options:\n");
+ printf("Syncer options:\n");
- SHOW_I("rate","KB/sec", cn.sconf.rate, DEF_SYNC_RATE);
- SHOW_I("group","", cn.sconf.group, DEF_SYNC_GROUP);
- SHOW_I("al-extents","", cn.sconf.al_extents, DEF_SYNC_AL_EXTENTS);
+ SHOW_I("rate","KB/sec", cn.sconf.rate, DEF_SYNC_RATE);
+ SHOW_I("group","", cn.sconf.group, DEF_SYNC_GROUP);
+ SHOW_I("al-extents","", cn.sconf.al_extents, DEF_SYNC_AL_EXTENTS);
- if( cn.sconf.skip ) printf(" skip-sync\n");
- if( cn.sconf.use_csums ) printf(" use-csums\n");
+ if( cn.sconf.skip ) printf(" skip-sync\n");
+ if( cn.sconf.use_csums ) printf(" use-csums\n");
+ }
return 0;
}
@@ -1256,13 +1262,13 @@
return 20;
}
- if( cn.cstate < StandAlone )
+ if( cn.state.s.conn == StandAlone && cn.state.s.disk == Diskless)
{
printf("Not configured\n");
return 0;
}
- printf("%s/%s\n",state_names[cn.state],state_names[cn.peer_state]);
+ printf("%s/%s\n",state_names[cn.state.s.role],state_names[cn.state.s.peer]);
return 0;
}
@@ -1299,13 +1305,13 @@
return 20;
}
- if( cn.cstate < StandAlone )
+ if( cn.state.s.conn == StandAlone && cn.state.s.disk == Diskless)
{
printf("Not configured\n");
return 0;
}
- printf("%s\n",cstate_names[cn.cstate]);
+ printf("%s\n",cstate_names[cn.state.s.conn]);
return 0;
}
More information about the drbd-cvs
mailing list