[DRBD-cvs] r1777 - in trunk: . drbd drbd/linux

www-data www-data at garcon.linbit.com
Mon Apr 4 17:19:43 CEST 2005


Author: phil
Date: 2005-04-04 17:19:41 +0200 (Mon, 04 Apr 2005)
New Revision: 1777

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_sizeof_sanity_check.c
   trunk/drbd/drbd_worker.c
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_config.h
Log:
Implemented the kernel part of item 16 (generation UUIDs)


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/ROADMAP	2005-04-04 15:19:41 UTC (rev 1777)
@@ -468,6 +468,10 @@
            NB: If they are needed, I think they can be implemented
                as special UUID values.
 
+  50% DONE. Kernel part is implemented, not tested. But testing
+            will only be possible after drbdmeta was updated. 
+            Drbdmeta still has no clue of gen-UUIDs, not drbdsetup.
+
 17 Something like
 
    drbdx: WARNING disk sizes more than 10% different

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_fs.c	2005-04-04 15:19:41 UTC (rev 1777)
@@ -703,7 +703,7 @@
 		nps = Outdated;
 		break;
 	case 5: /* peer was down, increase GENCNT ... */
-		drbd_md_inc(mdev,ConnectedCnt);
+		drbd_uuid_new_current(mdev);
 		nps = Outdated;
 		break;
 	case 6: /* Peer is primary, voluntarily outdate myself */
@@ -712,7 +712,7 @@
 		break;
 	default:
 		/* The script is broken ... */
-		drbd_md_inc(mdev,ConnectedCnt);
+		drbd_uuid_new_current(mdev);
 		nps = DUnknown;
 		ERR("outdate-peer helper returned %d (%d)\n",(r>>8)&0xff,r);
 	}
@@ -824,14 +824,9 @@
 			clear_bit(ON_PRI_INC_TIMEOUTEX,&mdev->flags);
 		}
 
-		if(newstate & Human) {
-			drbd_md_inc(mdev,HumanCnt);
-		} else if(newstate & TimeoutExpired ) {
-			drbd_md_inc(mdev,TimeoutCnt);
-		} else {
-			drbd_md_inc(mdev,
-				    mdev->state.s.conn >= Connected ?
-				    ConnectedCnt : ArbitraryCnt);
+		if ( (mdev->state.s.conn < WFReportParams &&
+		      mdev->uuid[Bitmap] == 0) || forced ) {
+			drbd_uuid_new_current(mdev);
 		}
 	}
 
@@ -982,10 +977,10 @@
 	return 0;
 }
 
-STATIC int drbd_ioctl_get_gen_cnt(struct Drbd_Conf *mdev, 
-				  struct ioctl_get_gen_cnt* arg)
+STATIC int drbd_ioctl_get_uuids(struct Drbd_Conf *mdev, 
+				struct ioctl_get_uuids* arg)
 {
-	struct ioctl_get_gen_cnt cn;
+	struct ioctl_get_uuids cn;
 	int i;
 
 	if( mdev->state.s.disk <= Failed ) {
@@ -994,10 +989,9 @@
 
 	memset(&cn,0,sizeof(cn));
 
-	for(i=Flags;i<=ArbitraryCnt;i++)
-		cn.gen_cnt[i]=mdev->gen_cnt[i];
-	cn.uuid = mdev->uuid;
-	cn.peer_uuid = mdev->peer_uuid;
+	for (i = Current; i < UUID_SIZE; i++) {
+		cn.uuid[i]=mdev->uuid[i];
+	}
 	cn.bits_set = drbd_bm_total_weight(mdev);
 	cn.current_size = drbd_get_capacity(mdev->this_bdev);
 
@@ -1307,8 +1301,8 @@
 		err = drbd_outdate_ioctl(mdev,(int *) arg);
 		break;
 
-	case DRBD_IOCTL_GET_GEN_CNT:
-		err=drbd_ioctl_get_gen_cnt(mdev,(void *)arg);
+	case DRBD_IOCTL_GET_UUIDS:
+		err=drbd_ioctl_get_uuids(mdev,(void *)arg);
 		break;
 
 	default:

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_int.h	2005-04-04 15:19:41 UTC (rev 1777)
@@ -293,7 +293,7 @@
 	RSDataRequest, // Used to ask for a data block
 	SyncParam,
 	ReportProtocol,
-	ReportGenCnt,
+	ReportUUIDs,
 	ReportSizes,
 	ReportState,
 	AuthChallenge,
@@ -334,7 +334,7 @@
 		[RSDataRequest]    = "RSDataRequest",
 		[SyncParam]        = "SyncParam",
 		[ReportProtocol]   = "ReportProtocol",
-		[ReportGenCnt]     = "ReportGenCnt",
+		[ReportUUIDs]     = "ReportUUIDs",
 		[ReportSizes]      = "ReportSizes",
 		[ReportState]      = "ReportState",
 		[AuthChallenge]    = "AuthChallenge",
@@ -461,13 +461,12 @@
 
 typedef struct {
 	Drbd_Header head;
-	u64         uuid;
 	u32         protocol;
 } __attribute((packed)) Drbd_Protocol_Packet;
 
 typedef struct {
 	Drbd_Header head;
-	u32         gen_cnt[GEN_CNT_SIZE];
+	u64         uuid[UUID_SIZE];
 } __attribute((packed)) Drbd_GenCnt_Packet;
 
 typedef struct {
@@ -636,7 +635,6 @@
 	MD_IO_ALLOWED,		// EXPLAIN
 	MD_DIRTY,		// current gen counts and flags not yet on disk
 	SYNC_STARTED,		// Needed to agree on the exact point in time..
-	UUID_CHANGED,           // UUID changed. Need fullsync.
 	UNIQUE,                 // Set on one node, cleared on the peer!
 	SPLIT_BRAIN_FIX,        // Set if split-brain-fix is configured
 };
@@ -706,8 +704,6 @@
 	/* volatile */ drbd_state_t state;
 	wait_queue_head_t cstate_wait; // TODO Rename into "misc_wait". 
 	sector_t la_size;     // last agreed disk size in sectors.
-	u64 uuid;
-	u64 peer_uuid;
 	unsigned int send_cnt;
 	unsigned int recv_cnt;
 	unsigned int read_cnt;
@@ -742,8 +738,9 @@
 	struct lru_cache* resync; // Used to track operations of resync...
 	atomic_t resync_locked;   // Number of locked elements in resync LRU
 	int open_cnt;
-	u32 gen_cnt[GEN_CNT_SIZE];
-	u32 *p_gen_cnt;
+	unsigned int md_flags;
+	u64 uuid[UUID_SIZE];
+	u64 *p_uuid;
 	atomic_t epoch_size;
 	spinlock_t ee_lock;
 	struct list_head active_ee; // IO in progress
@@ -836,10 +833,10 @@
 // drbd_meta-data.c (still in drbd_main.c)
 extern void drbd_md_write(drbd_dev *mdev);
 extern int drbd_md_read(drbd_dev *mdev);
-extern int drbd_md_compare(drbd_dev *mdev);
-extern void drbd_dump_md(drbd_dev *, int );
 // maybe define them below as inline?
-extern void drbd_md_inc(drbd_dev *mdev, enum MetaDataIndex order);
+extern void drbd_uuid_set_current(drbd_dev *mdev, u64 val);
+extern void drbd_uuid_new_current(drbd_dev *mdev);
+extern void drbd_uuid_reset_bm(drbd_dev *mdev);
 extern void drbd_md_set_flag(drbd_dev *mdev, int flags);
 extern void drbd_md_clear_flag(drbd_dev *mdev, int flags);
 extern int drbd_md_test_flag(drbd_dev *mdev, int flag);

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_main.c	2005-04-04 15:19:41 UTC (rev 1777)
@@ -50,6 +50,7 @@
 #include <linux/mm_inline.h>
 #include <linux/slab.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/random.h>
 
 #define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
@@ -542,7 +543,6 @@
 int _drbd_set_state(drbd_dev* mdev, drbd_state_t ns,enum chg_state_flags flags)
 {
 	drbd_state_t os;
-	char pb[160], *pbp;
 	int rv=1,warn_sync_abort=0;
 
 	os = mdev->state;
@@ -667,10 +667,6 @@
 		mod_timer(&mdev->resync_timer,jiffies);
 	}
 
-	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);
@@ -681,6 +677,12 @@
 		drbd_panic("No access to good data anymore.\n");
 	}
 
+	if ( os.s.conn != Connected && ns.s.conn == Connected && 
+	     mdev->p_uuid ) {
+		kfree(mdev->p_uuid);
+		mdev->p_uuid = 0;
+	}
+
 	return rv;
 }
 
@@ -948,7 +950,6 @@
 {
 	Drbd_Protocol_Packet p;
 
-	p.uuid   = cpu_to_be64(mdev->uuid);
 	p.protocol = cpu_to_be32(mdev->conf.wire_protocol);
 
 	return drbd_send_cmd(mdev,mdev->data.socket,ReportProtocol,
@@ -960,11 +961,11 @@
 	Drbd_GenCnt_Packet p;
 	int i;
 
-	for (i = Flags; i < GEN_CNT_SIZE; i++) {
-		p.gen_cnt[i] = cpu_to_be32(mdev->gen_cnt[i]);
+	for (i = Current; i < UUID_SIZE; i++) {
+		p.uuid[i] = cpu_to_be64(mdev->uuid[i]);
 	}
 
-	return drbd_send_cmd(mdev,mdev->data.socket,ReportGenCnt,
+	return drbd_send_cmd(mdev,mdev->data.socket,ReportUUIDs,
 			     (Drbd_Header*)&p,sizeof(p));
 }
 
@@ -1722,7 +1723,7 @@
 	ZAP(mdev->sync_conf);
 	// ZAP(mdev->data); Not yet!
 	// ZAP(mdev->meta); Not yet!
-	ZAP(mdev->gen_cnt);
+	ZAP(mdev->uuid);
 #undef ZAP
 	mdev->al_writ_cnt  =
 	mdev->bm_writ_cnt  =
@@ -2212,9 +2213,8 @@
 
 struct meta_data_on_disk {
 	u64 la_size;           // last agreed size.
-	u64 uuid;              // universally unique identifier
-	u64 peer_uuid;         // universally unique identifier
-	u32 gc[GEN_CNT_SIZE];  // generation counter
+	u64 uuid[UUID_SIZE];   // UUIDs.
+	u32 flags;             // MDF
 	u32 magic;
 	u32 md_size;
 	u32 al_offset;         // offset to this block
@@ -2240,19 +2240,17 @@
 	buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
 	memset(buffer,0,512);
 
-	flags = mdev->gen_cnt[Flags] & ~(MDF_Consistent|MDF_PrimaryInd|
-					 MDF_ConnectedInd|MDF_WasUpToDate);
+	flags = mdev->md_flags & ~(MDF_Consistent|MDF_PrimaryInd|
+				   MDF_ConnectedInd|MDF_WasUpToDate);
 	if (mdev->state.s.role == Primary)        flags |= MDF_PrimaryInd;
 	if (mdev->state.s.conn >= WFReportParams) flags |= MDF_ConnectedInd;
 	if (mdev->state.s.disk >  Inconsistent)   flags |= MDF_Consistent;
 	if (mdev->state.s.disk >  Outdated)       flags |= MDF_WasUpToDate;
-	mdev->gen_cnt[Flags] = flags;
+	mdev->md_flags = flags;
 
-	for (i = Flags; i < GEN_CNT_SIZE; i++)
-		buffer->gc[i]=cpu_to_be32(mdev->gen_cnt[i]);
+	for (i = Current; i < UUID_SIZE; i++)
+		buffer->uuid[i]=cpu_to_be64(mdev->uuid[i]);
 	buffer->la_size=cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
-	buffer->uuid=cpu_to_be64(mdev->uuid);
-	buffer->peer_uuid=cpu_to_be64(mdev->peer_uuid);
 
 	buffer->magic=cpu_to_be32(DRBD_MD_MAGIC);
 
@@ -2328,11 +2326,9 @@
 		goto err;
 	}
 
-	for(i=Flags;i<=ArbitraryCnt;i++)
-		mdev->gen_cnt[i]=be32_to_cpu(buffer->gc[i]);
+	for (i = Current; i < UUID_SIZE; i++)
+		mdev->uuid[i]=be64_to_cpu(buffer->uuid[i]);
 	mdev->la_size = be64_to_cpu(buffer->la_size);
-	mdev->uuid = be64_to_cpu(buffer->uuid);
-	mdev->peer_uuid = be64_to_cpu(buffer->peer_uuid);
 	mdev->sync_conf.al_extents = be32_to_cpu(buffer->al_nr_extents);
 	if (mdev->sync_conf.al_extents < 7)
 		mdev->sync_conf.al_extents = 127;
@@ -2349,105 +2345,60 @@
 	return rv;
 }
 
-#if DUMP_MD >= 1
-#define MeGC(x) mdev->gen_cnt[x]
-#define PeGC(x) mdev->p_gen_cnt[x]
 
-void drbd_dump_md(drbd_dev *mdev, int verbose)
+void drbd_uuid_set_current(drbd_dev *mdev, u64 val)
 {
-	INFO("I am(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
-		mdev->state.s.role == Primary ? 'P':'S',
-		MeGC(Flags) & MDF_Consistent ? '1' : '0',
-		MeGC(HumanCnt),
-		MeGC(TimeoutCnt),
-		MeGC(ConnectedCnt),
-		MeGC(ArbitraryCnt),
-		MeGC(Flags) & MDF_PrimaryInd   ? '1' : '0',
-		MeGC(Flags) & MDF_ConnectedInd ? '1' : '0');
-	if (mdev->p_gen_cnt) {
-		INFO("Peer(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
-			mdev->state.s.peer == Primary ? 'P':'S',
-			PeGC(Flags) & MDF_Consistent ? '1' : '0',
-			PeGC(HumanCnt),
-			PeGC(TimeoutCnt),
-			PeGC(ConnectedCnt),
-			PeGC(ArbitraryCnt),
-			PeGC(Flags) & MDF_PrimaryInd   ? '1' : '0',
-			PeGC(Flags) & MDF_ConnectedInd ? '1' : '0');
+	mdev->uuid[Current] = val;
+	if (mdev->state.s.role == Primary) {
+		mdev->uuid[Current] |= 1;
 	} else {
-		INFO("Peer Unknown.\n");
+		mdev->uuid[Current] &= ~((u64)1);
 	}
-	if (verbose) {
-		/* TODO
-		 * dump activity log and bitmap summary,
-		 * and maybe other statistics
-		 */
+}
+
+void drbd_uuid_new_current(drbd_dev *mdev)
+{
+	D_ASSERT(mdev->uuid[Bitmap] = 0);
+	mdev->uuid[Bitmap] = mdev->uuid[Current];
+	get_random_bytes(&mdev->uuid[Current], sizeof(u64));
+	if (mdev->state.s.role == Primary) {
+		mdev->uuid[Current] |= 1;
+	} else {
+		mdev->uuid[Current] &= ~((u64)1);
 	}
 }
 
-#undef MeGC
-#undef PeGC
-#else
-void drbd_dump_md(drbd_dev *mdev, Drbd_Parameter_Packet *peer, int verbose)
-{ /* do nothing */ }
-#endif
-
-//  Returns  1 if I have the good bits,
-//           0 if both are nice
-//          -1 if the partner has the good bits.
-int drbd_md_compare(drbd_dev *mdev)
+void drbd_uuid_reset_bm(drbd_dev *mdev)
 {
 	int i;
-	u32 self,peer;
 
-	self = mdev->gen_cnt[Flags] & MDF_Consistent;
-	peer = mdev->p_gen_cnt[Flags] & MDF_Consistent;
-	if( self > peer ) return 1;
-	if( self < peer ) return -1;
+	if (mdev->uuid[Bitmap] == 0) return;
 
-	self = mdev->gen_cnt[Flags] & MDF_WasUpToDate;
-	peer = mdev->p_gen_cnt[Flags] & MDF_WasUpToDate;
-	if( self > peer ) return 1;
-	if( self < peer ) return -1;
-
-	for(i=HumanCnt;i<=ArbitraryCnt;i++) {
-		self = mdev->gen_cnt[i];
-		peer = mdev->p_gen_cnt[i];
-		if( self > peer ) return 1;
-		if( self < peer ) return -1;
+	for ( i=History_start ; i<History_end ; i++ ) {
+		mdev->uuid[i+1] = mdev->uuid[i];
 	}
 
-	self = mdev->gen_cnt[Flags] & MDF_PrimaryInd;
-	peer = mdev->p_gen_cnt[Flags] & MDF_PrimaryInd;
-	if( self > peer ) return 1;
-	if( self < peer ) return -1;
-
-	return 0;
+	mdev->uuid[History_start]=mdev->uuid[Bitmap];
+	mdev->uuid[Bitmap]=0;
 }
 
-/* THINK do these have to be protected by some lock ? */
-void drbd_md_inc(drbd_dev *mdev, enum MetaDataIndex order)
-{
-	set_bit(MD_DIRTY,&mdev->flags);
-	mdev->gen_cnt[order]++;
-}
 void drbd_md_set_flag(drbd_dev *mdev, int flag)
 {
-	if ( (mdev->gen_cnt[Flags] & flag) != flag) {
+	if ( (mdev->md_flags & flag) != flag) {
 		set_bit(MD_DIRTY,&mdev->flags);
-		mdev->gen_cnt[Flags] |= flag;
+		mdev->md_flags |= flag;
 	}
 }
 void drbd_md_clear_flag(drbd_dev *mdev, int flag)
 {
-	if ( (mdev->gen_cnt[Flags] & flag) != 0 ) {
+	if ( (mdev->md_flags & flag) != 0 ) {
 		set_bit(MD_DIRTY,&mdev->flags);
-		mdev->gen_cnt[Flags] &= ~flag;
+		mdev->md_flags &= ~flag;
 	}
 }
 int drbd_md_test_flag(drbd_dev *mdev, int flag)
 {
-	return ((mdev->gen_cnt[Flags] & flag) != 0);
+	return ((mdev->md_flags & flag) != 0);
 }
 
 module_init(drbd_init)

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_receiver.c	2005-04-04 15:19:41 UTC (rev 1777)
@@ -1257,123 +1257,133 @@
 	return TRUE;
 }
 
+/*
+  100   after split brain try auto recover
+    2   SyncSource set BitMap
+    1   SyncSource use BitMap
+    0   no Sync
+   -1   SyncTarget use BitMap
+   -2   SyncTarget set BitMap
+ -100   after split brain, disconnect
+-1000   unrelated data
+ */
+static int drbd_uuid_compare(drbd_dev *mdev)
+{
+	u64 self, peer;
+	int i,j;
+
+	self = mdev->uuid[Current] & ~((u64)1);
+	peer = mdev->p_uuid[Current] & ~((u64)1);
+
+	if (self == UUID_JUST_CREATED &&
+	    peer == UUID_JUST_CREATED) return 0;
+
+	if (self == UUID_JUST_CREATED && 
+	    peer != UUID_JUST_CREATED) return -2;
+
+	if (self != UUID_JUST_CREATED && 
+	    peer == UUID_JUST_CREATED) return 2;
+
+	if (self == peer) return 0;
+
+	peer = mdev->p_uuid[Bitmap] & ~((u64)1);
+	if (self == peer) return -1;
+
+	for ( i=History_start ; i<=History_end ; i++ ) {
+		peer = mdev->p_uuid[i];
+		if (self == peer) return -2;
+	}
+
+	self = mdev->uuid[Bitmap] & ~((u64)1);
+	peer = mdev->p_uuid[Current] & ~((u64)1);
+
+	if (self == peer) return 1;
+	
+	for ( i=History_start ; i<=History_end ; i++ ) {
+		self = mdev->uuid[i] & ~((u64)1);
+		if (self == peer) return 2;
+	}
+
+	self = mdev->uuid[Bitmap] & ~((u64)1);
+	peer = mdev->p_uuid[Bitmap] & ~((u64)1);
+
+	if (self == peer) return 100;
+
+	for ( i=History_start ; i<=History_end ; i++ ) {
+		self = mdev->p_uuid[i] & ~((u64)1);
+		for ( j=History_start ; j<=History_end ; j++ ) {
+			peer = mdev->p_uuid[j] & ~((u64)1);
+			if (self == peer) return -100;
+		}
+	}
+
+	return -1000;
+}
+
 /* 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)
 {
-	int have_good,sync;
+	int hg;
 	drbd_conns_t rv = conn_mask;
 
-	have_good = drbd_md_compare(mdev);
+	hg = drbd_uuid_compare(mdev);
 
-	if(have_good==0) {
-		if (drbd_md_test_flag(mdev,MDF_PrimaryInd)) {
-			/* gen counts compare the same, but I have the
-			 * PrimaryIndicator set.  so the peer has, too
-			 * (otherwise this would not compare the same).
-			 * so we had a split brain!
-			 *
-			 * FIXME maybe log MDF_SplitBran into metadata,
-			 * and refuse to do anything until told otherwise!
-			 *
-			 * for now: just go StandAlone.
-			 */
-			ALERT("Split-Brain detected, dropping connection!\n");
-			drbd_force_state(mdev,NS(conn,StandAlone));
-			drbd_thread_stop_nowait(&mdev->receiver);
-			return conn_mask;
-		}
-		sync=0;
-	} else {
-		sync=1;
+	if (abs(hg) >= 100) {
+		ALERT("Split-Brain detected, dropping connection!\n");
+		drbd_force_state(mdev,NS(conn,StandAlone));
+		drbd_thread_stop_nowait(&mdev->receiver);
+		return conn_mask;
 	}
 
-	drbd_dump_md(mdev,0);
-	// INFO("have_good=%d sync=%d\n", have_good, sync);
-
-	if (have_good > 0 && mdev->state.s.disk <= Inconsistent ) {
-		/* doh. I cannot become SyncSource when I am inconsistent!
-		 */
+	if (hg > 0 && mdev->state.s.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);
 		return conn_mask;
 	}
-	if (have_good < 0 && !(mdev->p_gen_cnt[Flags] & MDF_Consistent) ) {
-		/* doh. Peer cannot become SyncSource when inconsistent
-		 */
-		ERR("I shall become SyncTarget, but Peer is inconsistent!\n");
+	if (hg < 0 && mdev->state.s.role == Primary ) {
+		ERR("I shall become SyncTarget, but I am primary!\n");
 		drbd_force_state(mdev,NS(conn,StandAlone));
 		drbd_thread_stop_nowait(&mdev->receiver);
 		return conn_mask;
 	}
 
-	if ( mdev->sync_conf.skip && sync ) {
-		return have_good == 1 ? SkippedSyncS : SkippedSyncT ;
+	if (abs(hg) >= 2) {
+		drbd_md_set_flag(mdev,MDF_FullSync);
+		drbd_md_write(mdev);
+
+		drbd_bm_set_all(mdev);
+		drbd_bm_write(mdev);
+
+		drbd_md_clear_flag(mdev,MDF_FullSync);
+		drbd_md_write(mdev);
 	}
 
-	if( sync ) {
-		if( test_bit(UUID_CHANGED,&mdev->flags) ) {
-			WARN("Peer presented a new UUID -> full sync.\n");
-			drbd_bm_set_all(mdev);
-			clear_bit(UUID_CHANGED, &mdev->flags);
-		}
-
-		if(have_good == 1) {
-			D_ASSERT(drbd_md_test_flag(mdev,MDF_Consistent));
-			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.s.role == Primary) &&
-			     drbd_md_test_flag(mdev,MDF_Consistent) ) {
-				/* FIXME
-				 * allow Primary become SyncTarget if it was
-				 * diskless, and now had a storage reattached.
-				 * only somewhere the MDF_Consistent flag is
-				 * set where it should not... I think.
-				 */
-				ERR("Current Primary shall become sync TARGET!"
-				    " Aborting to prevent data corruption.\n");
-				drbd_force_state(mdev,NS(conn,StandAlone));
-				drbd_thread_stop_nowait(&mdev->receiver);
-				return conn_mask;
-			}
-			drbd_md_clear_flag(mdev,MDF_Consistent);
-			rv = WFBitMapT;
-		}
+	if (hg > 0) { // become sync source.
+		D_ASSERT(drbd_md_test_flag(mdev,MDF_Consistent));
+		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 if (hg < 0) { // become sync target
+		drbd_md_clear_flag(mdev,MDF_Consistent);
+		drbd_uuid_set_current(mdev,mdev->p_uuid[Bitmap]);
+		rv = WFBitMapT;		
 	} else {
 		rv = Connected;
 		drbd_bm_lock(mdev);   // {
 		if(drbd_bm_total_weight(mdev)) {
-			if (drbd_md_test_flag(mdev,MDF_Consistent)) {
-				/* We are not going to do a resync but there
-				   are marks in the bitmap.
-				   (Could be from the AL, or someone used
-				   the write_gc.pl program)
-				   Clean the bitmap...
-				 */
-				INFO("No resync -> clearing bit map.\n");
-				drbd_bm_clear_all(mdev);
-				drbd_bm_write(mdev);
-			} else {
-				WARN("I am inconsistent, but there is no sync? BOTH nodes inconsistent!\n");
-			}
+			INFO("No resync -> clearing bit map.\n");
+			drbd_bm_clear_all(mdev);
+			drbd_bm_write(mdev);
 		}
 		drbd_bm_unlock(mdev); // }
 	}
 
-	if (have_good == -1) {
-		/* Sync-Target has to adopt source's gen_cnt. */
-		int i;
-		for(i=HumanCnt;i<GEN_CNT_SIZE;i++) {
-			mdev->gen_cnt[i]=mdev->p_gen_cnt[i];
-		}
-	}
 	return rv;
 }
 
@@ -1403,11 +1413,6 @@
 		return FALSE;
 	}
 
-	if( mdev->peer_uuid != be64_to_cpu(p->uuid) ) {
-		mdev->peer_uuid = be64_to_cpu(p->uuid);
-		set_bit(UUID_CHANGED, &mdev->flags);
-	}
-
 	return TRUE;
 }
 
@@ -1459,10 +1464,8 @@
 	drbd_determin_dev_size(mdev);
 	drbd_bm_unlock(mdev); // }
 	
-	if (mdev->p_gen_cnt) {
+	if (mdev->p_uuid) {
 		nconn=drbd_sync_handshake(mdev);
-		kfree(mdev->p_gen_cnt);
-		mdev->p_gen_cnt = 0;
 		if(nconn == conn_mask) return FALSE;
 
 		if(drbd_request_state(mdev,NS(conn,nconn)) <= 0) {
@@ -1489,24 +1492,24 @@
 	return TRUE;
 }
 
-STATIC int receive_gen_cnt(drbd_dev *mdev, Drbd_Header *h)
+STATIC int receive_uuids(drbd_dev *mdev, Drbd_Header *h)
 {
 	Drbd_GenCnt_Packet *p = (Drbd_GenCnt_Packet*)h;
-	u32 *p_gen_cnt;
+	u64 *p_uuid;
 	int i;
 
 	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
 	if (drbd_recv(mdev, h->payload, h->length) != h->length)
 		return FALSE;
 
-	p_gen_cnt = kmalloc(sizeof(u32)*GEN_CNT_SIZE, GFP_KERNEL);
+	p_uuid = kmalloc(sizeof(u64)*UUID_SIZE, GFP_KERNEL);
 
-	for (i = Flags; i < GEN_CNT_SIZE; i++) {
-		p_gen_cnt[i] = be32_to_cpu(p->gen_cnt[i]);
+	for (i = Current; i < UUID_SIZE; i++) {
+		p_uuid[i] = be64_to_cpu(p->uuid[i]);
 	}
 
-	if ( mdev->p_gen_cnt ) kfree(mdev->p_gen_cnt);
-	mdev->p_gen_cnt = p_gen_cnt;
+	if ( mdev->p_uuid ) kfree(mdev->p_uuid);
+	mdev->p_uuid = p_uuid;
 
 	return TRUE;
 }
@@ -1526,10 +1529,10 @@
 	nconn = mdev->state.s.conn;
 	if (nconn == WFReportParams ) nconn = Connected;
 
-	if (mdev->p_gen_cnt) {
+	if (mdev->p_uuid && mdev->state.s.conn == Connected) {
 		nconn=drbd_sync_handshake(mdev);
-		kfree(mdev->p_gen_cnt);
-		mdev->p_gen_cnt = 0;
+		kfree(mdev->p_uuid);
+		mdev->p_uuid = 0;
 		if(nconn == conn_mask) return FALSE;
 	}
 
@@ -1730,7 +1733,7 @@
 	[RSDataRequest]    = receive_DataRequest, //receive_RSDataRequest,
 	[SyncParam]        = receive_SyncParam,
 	[ReportProtocol]   = receive_protocol,
-	[ReportGenCnt]     = receive_gen_cnt,
+	[ReportUUIDs]     = receive_uuids,
 	[ReportSizes]      = receive_sizes,
 	[ReportState]      = receive_state,
 };
@@ -1876,10 +1879,13 @@
 		drbd_thread_start(&mdev->worker);
 	}
 
-	if ( test_bit(SPLIT_BRAIN_FIX,&mdev->flags) && 
-	     mdev->state.s.role == Primary) {
-		drbd_disks_t nps = drbd_try_outdate_peer(mdev);
-		drbd_request_state(mdev,NS(pdsk,nps));
+	if ( mdev->state.s.role == Primary ) {
+		if ( test_bit(SPLIT_BRAIN_FIX,&mdev->flags) ) {
+			drbd_disks_t nps = drbd_try_outdate_peer(mdev);
+			drbd_request_state(mdev,NS(pdsk,nps));
+		} else {
+			drbd_uuid_new_current(mdev);
+		}
 		drbd_md_write(mdev);
 	}
 

Modified: trunk/drbd/drbd_sizeof_sanity_check.c
===================================================================
--- trunk/drbd/drbd_sizeof_sanity_check.c	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_sizeof_sanity_check.c	2005-04-04 15:19:41 UTC (rev 1777)
@@ -23,7 +23,7 @@
 	SZO(struct ioctl_syncer_config,	 32)
 	SZO(struct ioctl_wait,		 16)
 	SZO(struct ioctl_get_config,	560)
-	SZO(struct ioctl_get_gen_cnt,    48)
+	SZO(struct ioctl_get_uuids,      48)
 	if (err) printk("<3>ioctls won't work, aborting\n");
 	return err;
 }

Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/drbd_worker.c	2005-04-04 15:19:41 UTC (rev 1777)
@@ -390,6 +390,9 @@
 	mdev->rs_total  = 0;
 	mdev->rs_paused = 0;
 
+	drbd_uuid_set_current(mdev,mdev->p_uuid[Current]);
+	drbd_uuid_reset_bm(mdev);
+
 	drbd_request_state(mdev,NS3(conn,Connected,
 				    disk,UpToDate,
 				    pdsk,UpToDate));

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/linux/drbd.h	2005-04-04 15:19:41 UTC (rev 1777)
@@ -273,6 +273,7 @@
 #define MDF_FullSync        (1<<__MDF_FullSync)
 #define MDF_WasUpToDate     (1<<__MDF_WasUpToDate)
 
+/* MetaDataIndex is scheduled for removal! */
 enum MetaDataIndex {
 	Flags,			/* Consistency flag,connected-ind,primary-ind */
 	HumanCnt,		/* human-intervention-count */
@@ -282,11 +283,19 @@
 	GEN_CNT_SIZE		/* MUST BE LAST! (and Flags must stay first...) */
 };
 
-struct ioctl_get_gen_cnt {
-	OUT __u64        uuid;
-	OUT __u64        peer_uuid;
+enum UuidIndex {
+	Current,
+	Bitmap,
+	History_start,
+	History_end,
+	UUID_SIZE
+};
+
+#define UUID_JUST_CREATED ((__u64)4)
+
+struct ioctl_get_uuids {
+	OUT __u64        uuid[UUID_SIZE];
 	OUT __u64        current_size;
-	OUT __u32        gen_cnt[GEN_CNT_SIZE];	/* generation counter */
 	OUT unsigned int bits_set;
 };
 
@@ -312,7 +321,7 @@
 #define DRBD_IOCTL_UNCONFIG_DISK    _IO ( DRBD_IOCTL_LETTER, 0x13 )
 #define DRBD_IOCTL_SET_STATE_FLAGS  _IOW( DRBD_IOCTL_LETTER, 0x14, drbd_role_t )
 #define DRBD_IOCTL_OUTDATE_DISK     _IOW( DRBD_IOCTL_LETTER, 0x15, int )
-#define DRBD_IOCTL_GET_GEN_CNT      _IOR( DRBD_IOCTL_LETTER, 0x15, struct ioctl_get_gen_cnt )
+#define DRBD_IOCTL_GET_UUIDS        _IOR( DRBD_IOCTL_LETTER, 0x16, struct ioctl_get_uuids )
 
 
 #endif

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2005-04-04 12:05:08 UTC (rev 1776)
+++ trunk/drbd/linux/drbd_config.h	2005-04-04 15:19:41 UTC (rev 1777)
@@ -30,10 +30,6 @@
 
 //#define DBG_SPINLOCKS   // enables MUST_HOLD macro (assertions for spinlocks)
 //#define DBG_ASSERTS     // drbd_assert_breakpoint() function
-//#define DUMP_MD 1       // Dump metadata to syslog upon connect
-#define DUMP_MD 2       // Dump even all cstate changes (I like it!)
-//#define DUMP_MD 3       // Dump even all meta data access
-                          // (don't! unless we track down a bug...)
 
 //#define PARANOIA // some extra checks
 



More information about the drbd-cvs mailing list