[DRBD-cvs] r1722 - in trunk: . drbd

svn at svn.drbd.org svn at svn.drbd.org
Sat Jan 15 11:03:10 CET 2005


Author: phil
Date: 2005-01-15 11:03:08 +0100 (Sat, 15 Jan 2005)
New Revision: 1722

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
Log:
Worked on item 2 of the Roadmap
 "Drop the Drbd_Parameter_Packet"
still untested.



Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2005-01-14 20:02:24 UTC (rev 1721)
+++ trunk/ROADMAP	2005-01-15 10:03:08 UTC (rev 1722)
@@ -8,15 +8,12 @@
   90% DONE
 
 2 Drop the Drbd_Parameter_Packet.
-  Replace the Drbd_Parameter_Packet by a more general and 
-  extensible mechanism.
+  Replace the Drbd_Parameter_Packet by 4 small packets:
+  Protocol, GenCnt, Sizes and State.
+  The receiving code of these small packets is sane, compared
+  to that huge receive_params() function we had before.
+  40% DONE
 
-  Sanitize ioctls to inlcude a standard device information struct
-  at the beginning, including the expected API version.
-  Consider using DRBD ioctls with some char device similar to
-  /dev/mapper/control
-  0% DONE
-
 3 Authenticate the peer upon connect by using a shared secret. 
   Configuration file syntax:  net { auth-secret "secret-word" }
   Using a challenge-response authentication within the new
@@ -353,12 +350,20 @@
   section (like handlers, startup, disk, net and syncer)
   are inherited from the common section, if they are not
   defined in a resource section.
+  0% DONE
 
 13 Introduce a UUID (universally unique identifier) in the
   meta data. One purpose is to tag the bitmap with this UUID. 
   If the peer's UUID is different to what we expect we know that 
   we have to do a full sync....
+  99% DONE
 
+14 Sanitize ioctls to inlcude a standard device information struct
+  at the beginning, including the expected API version.
+  Consider using DRBD ioctls with some char device similar to
+  /dev/mapper/control
+  0% DONE
+
 plus-banches:
 ----------------------
 

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2005-01-14 20:02:24 UTC (rev 1721)
+++ trunk/drbd/drbd_fs.c	2005-01-15 10:03:08 UTC (rev 1722)
@@ -771,7 +771,8 @@
 
 	if (mdev->state.s.conn >= WFReportParams) {
 		/* if this was forced, we should consider sync */
-		drbd_send_param(mdev,forced);
+		if(forced) drbd_send_gen_cnt(mdev);
+		drbd_send_state(mdev);
 	}
 
 	return 0;
@@ -1001,7 +1002,8 @@
 			err = -EBUSY;
 			break;
 		}
-		if ( mdev->state == Secondary && mdev->o_state == Secondary) {
+		if ( mdev->state.s.role == Secondary && 
+		     mdev->state.s.peer == Secondary) {
 			err = -EINPROGRESS;
 			break;
 		}
@@ -1011,7 +1013,10 @@
 		drbd_determin_dev_size(mdev);
 		drbd_md_write(mdev); // Write mdev->la_size to disk.
 		drbd_bm_unlock(mdev);
-		if (mdev->state.s.conn == Connected) drbd_send_param(mdev,1);
+		if (mdev->state.s.conn == Connected) {
+			drbd_send_gen_cnt(mdev); // to start sync...
+			drbd_send_sizes(mdev);
+		}
 		break;
 
 	case DRBD_IOCTL_SET_NET_CONFIG:

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2005-01-14 20:02:24 UTC (rev 1721)
+++ trunk/drbd/drbd_int.h	2005-01-15 10:03:08 UTC (rev 1722)
@@ -306,7 +306,6 @@
 	DataReply,     // Response to DataRequest
 	RSDataReply,   // Response to RSDataRequest
 	Barrier,
-	ReportParams,
 	ReportBitMap,
 	BecomeSyncTarget,
 	BecomeSyncSource,
@@ -314,6 +313,10 @@
 	DataRequest,   // Used to ask for a data block
 	RSDataRequest, // Used to ask for a data block
 	SyncParam,
+	ReportProtocol,
+	ReportGenCnt,
+	ReportSizes,
+	ReportState,
 
 	Ping,         // These are sent on the meta socket...
 	PingAck,
@@ -341,7 +344,6 @@
 		[DataReply]        = "DataReply",
 		[RSDataReply]      = "RSDataReply",
 		[Barrier]          = "Barrier",
-		[ReportParams]     = "ReportParams",
 		[ReportBitMap]     = "ReportBitMap",
 		[BecomeSyncTarget] = "BecomeSyncTarget",
 		[BecomeSyncSource] = "BecomeSyncSource",
@@ -349,6 +351,10 @@
 		[DataRequest]      = "DataRequest",
 		[RSDataRequest]    = "RSDataRequest",
 		[SyncParam]        = "SyncParam",
+		[ReportProtocol]   = "ReportProtocol",
+		[ReportGenCnt]     = "ReportGenCnt",
+		[ReportSizes]      = "ReportSizes",
+		[ReportState]      = "ReportState",
 		[Ping]             = "Ping",
 		[PingAck]          = "PingAck",
 		[RecvAck]          = "RecvAck",
@@ -466,26 +472,30 @@
 	u32         group;
 } __attribute((packed)) Drbd_SyncParam_Packet;
 
-/* FIXME add more members here, until we introduce a new fixed size
- * protocol version handshake packet! */
 typedef struct {
 	Drbd_Header head;
-	u64         p_size;  // size of disk
-	u64         u_size;  // user requested size
 	u64         uuid;
-	u32         state;
 	u32         protocol;
-	u32         version;
+} __attribute((packed)) Drbd_Protocol_Packet;
+
+typedef struct {
+	Drbd_Header head;
 	u32         gen_cnt[GEN_CNT_SIZE];
-	u32         sync_rate;
-	u32         sync_use_csums;
-	u32         skip_sync;
-	u32         sync_group;
-	u32         flags;   // flags & 1 -> reply call drbd_send_param(mdev);
-	u32         magic;   //make sure packet is a multiple of 8 Byte
-} __attribute((packed)) Drbd_Parameter_Packet;
+} __attribute((packed)) Drbd_GenCnt_Packet;
 
 typedef struct {
+	Drbd_Header head;
+	u64         d_size;  // size of disk
+	u64         u_size;  // user requested size
+	u64         c_size;  // current exported size
+} __attribute((packed)) Drbd_Sizes_Packet;
+
+typedef struct {
+	Drbd_Header head;
+	u32         state;
+} __attribute((packed)) Drbd_State_Packet;
+
+typedef struct {
 	u64       size;
 	u32       state;
 	u32       blksize;
@@ -503,7 +513,10 @@
 	Drbd_Barrier_Packet      Barrier;
 	Drbd_BarrierAck_Packet   BarrierAck;
 	Drbd_SyncParam_Packet    SyncParam;
-	Drbd_Parameter_Packet    Parameter;
+	Drbd_Protocol_Packet     Protocol;
+	Drbd_Sizes_Packet        Sizes;
+	Drbd_GenCnt_Packet       GenCnt;
+	Drbd_State_Packet        State;
 	Drbd_BlockRequest_Packet BlockRequest;
 } __attribute((packed)) Drbd_Polymorph_Packet;
 
@@ -627,6 +640,7 @@
 	SENT_DISK_FAILURE,	// sending it once is enough
 	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.
 };
 
 struct drbd_bitmap; // opaque for Drbd_Conf
@@ -725,6 +739,7 @@
 	atomic_t resync_locked;   // Number of locked elements in resync LRU
 	int open_cnt;
 	u32 gen_cnt[GEN_CNT_SIZE];
+	u32 *p_gen_cnt;
 	atomic_t epoch_size;
 	spinlock_t ee_lock;
 	struct list_head free_ee;   // available
@@ -777,7 +792,10 @@
 extern void drbd_free_sock(drbd_dev *mdev);
 extern int drbd_send(drbd_dev *mdev, struct socket *sock,
 		     void* buf, size_t size, unsigned msg_flags);
-extern int drbd_send_param(drbd_dev *mdev, int flags);
+extern int drbd_send_protocol(drbd_dev *mdev);
+extern int drbd_send_gen_cnt(drbd_dev *mdev);
+extern int drbd_send_sizes(drbd_dev *mdev);
+extern int drbd_send_state(drbd_dev *mdev);
 extern int _drbd_send_cmd(drbd_dev *mdev, struct socket *sock,
 			  Drbd_Packet_Cmd cmd, Drbd_Header *h,
 			  size_t size, unsigned msg_flags);
@@ -805,8 +823,8 @@
 // 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,Drbd_Parameter_Packet *partner);
-extern void drbd_dump_md(drbd_dev *, Drbd_Parameter_Packet *, int );
+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_md_set_flag(drbd_dev *mdev, int flags);

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2005-01-14 20:02:24 UTC (rev 1721)
+++ trunk/drbd/drbd_main.c	2005-01-15 10:03:08 UTC (rev 1722)
@@ -385,7 +385,7 @@
 
 	if(!send) return ok;
 
-	ok = drbd_send_param(mdev,0);
+	ok = drbd_send_state(mdev);
 	WARN("Notified peer that my disk is broken.\n");
 
 	D_ASSERT(drbd_md_test_flag(mdev,MDF_FullSync));
@@ -598,13 +598,14 @@
 	/*  Added disk, tell peer.  */
 	if ( os.s.disk == Diskless && ns.s.disk >= Inconsistent &&
 	     ns.s.conn >= Connected ) {
-		drbd_send_param(mdev,1);
+		drbd_send_sizes(mdev);
+		drbd_send_state(mdev);
 	}
 
 	/*  Removed disk, tell peer.  */
 	if ( os.s.disk >= Inconsistent && ns.s.disk == Diskless &&
 	     ns.s.conn >= Connected ) {
-		drbd_send_param(mdev,0);
+		drbd_send_state(mdev);
 	}
 }
 
@@ -809,62 +810,74 @@
 int drbd_send_sync_param(drbd_dev *mdev, struct syncer_config *sc)
 {
 	Drbd_SyncParam_Packet p;
-	int ok;
 
 	p.rate      = cpu_to_be32(sc->rate);
 	p.use_csums = cpu_to_be32(sc->use_csums);
 	p.skip      = cpu_to_be32(sc->skip);
 	p.group     = cpu_to_be32(sc->group);
 
-	ok = drbd_send_cmd(mdev,mdev->data.socket,SyncParam,(Drbd_Header*)&p,sizeof(p));
-	if ( ok
-	     && (mdev->state.s.conn == SkippedSyncS || 
-		 mdev->state.s.conn == SkippedSyncT)
-	     && !sc->skip )
-	{
-		/* FIXME EXPLAIN. I think this cannot work properly! -lge */
-		drbd_request_state(mdev,NS(conn,WFReportParams));
-		ok = drbd_send_param(mdev,0);
+	return drbd_send_cmd(mdev,mdev->data.socket,SyncParam,(Drbd_Header*)&p,sizeof(p));
+}
+
+int drbd_send_protocol(drbd_dev *mdev)
+{
+	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,
+			     (Drbd_Header*)&p,sizeof(p));
+}
+
+int drbd_send_gen_cnt(drbd_dev *mdev)
+{
+	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]);
 	}
-	return ok;
+
+	return drbd_send_cmd(mdev,mdev->data.socket,ReportGenCnt,
+			     (Drbd_Header*)&p,sizeof(p));
 }
 
-int drbd_send_param(drbd_dev *mdev, int flags)
+int drbd_send_sizes(drbd_dev *mdev)
 {
-	Drbd_Parameter_Packet p;
-	int i, ok, have_disk;
-	unsigned long m_size; // sector_t ??
+	Drbd_Sizes_Packet p;
+	int ok, have_disk;
+	sector_t d_size;
 
 	have_disk=inc_local(mdev);
 	if(have_disk) {
 		D_ASSERT(mdev->backing_bdev);
-		if (mdev->md_index == -1 ) m_size = drbd_md_ss(mdev)>>1;
-		else m_size = drbd_get_capacity(mdev->backing_bdev)>>1;
-	} else m_size = 0;
+		if (mdev->md_index == -1 ) d_size = drbd_md_ss(mdev)>>1;
+		else d_size = drbd_get_capacity(mdev->backing_bdev)>>1;
+	} else d_size = 0;
 
 	p.u_size = cpu_to_be64(mdev->lo_usize);
-	p.p_size = cpu_to_be64(m_size);
-	p.uuid   = cpu_to_be64(mdev->uuid);
+	p.d_size = cpu_to_be64(d_size);
+	p.c_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
 
-	p.state    = cpu_to_be32(mdev->state.i);
-	p.protocol = cpu_to_be32(mdev->conf.wire_protocol);
-	p.version  = cpu_to_be32(PRO_VERSION);
+	ok = drbd_send_cmd(mdev,mdev->data.socket,ReportSizes,
+			   (Drbd_Header*)&p,sizeof(p));
+	if (have_disk) dec_local(mdev);
 
-	for (i = Flags; i < GEN_CNT_SIZE; i++) {
-		p.gen_cnt[i] = cpu_to_be32(mdev->gen_cnt[i]);
-	}
-	p.sync_rate      = cpu_to_be32(mdev->sync_conf.rate);
-	p.sync_use_csums = cpu_to_be32(mdev->sync_conf.use_csums);
-	p.skip_sync      = cpu_to_be32(mdev->sync_conf.skip);
-	p.sync_group     = cpu_to_be32(mdev->sync_conf.group);
-	p.flags          = cpu_to_be32(flags);
-	p.magic          = BE_DRBD_MAGIC;
-
-	ok = drbd_send_cmd(mdev,mdev->data.socket,ReportParams,(Drbd_Header*)&p,sizeof(p));
-	if (have_disk) dec_local(mdev);
 	return ok;
 }
 
+
+int drbd_send_state(drbd_dev *mdev)
+{
+	Drbd_State_Packet p;
+
+	p.state    = cpu_to_be32(mdev->state.i);
+
+	return drbd_send_cmd(mdev,mdev->data.socket,ReportState,
+			     (Drbd_Header*)&p,sizeof(p));
+}
+
 /* See the comment at receive_bitmap() */
 int _drbd_send_bitmap(drbd_dev *mdev)
 {
@@ -2176,9 +2189,9 @@
 
 #if DUMP_MD >= 1
 #define MeGC(x) mdev->gen_cnt[x]
-#define PeGC(x) be32_to_cpu(peer->gen_cnt[x])
+#define PeGC(x) mdev->p_gen_cnt[x]
 
-void drbd_dump_md(drbd_dev *mdev, Drbd_Parameter_Packet *peer, int verbose)
+void drbd_dump_md(drbd_dev *mdev, int verbose)
 {
 	INFO("I am(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
 		mdev->state.s.role == Primary ? 'P':'S',
@@ -2189,9 +2202,9 @@
 		MeGC(ArbitraryCnt),
 		MeGC(Flags) & MDF_PrimaryInd   ? '1' : '0',
 		MeGC(Flags) & MDF_ConnectedInd ? '1' : '0');
-	if (peer) {
+	if (mdev->p_gen_cnt) {
 		INFO("Peer(%c): %c:%08x:%08x:%08x:%08x:%c%c\n",
-			((drbd_state_t)be32_to_cpu(peer->state)).s.role == Primary ? 'P':'S',
+			mdev->state.s.peer == Primary ? 'P':'S',
 			PeGC(Flags) & MDF_Consistent ? '1' : '0',
 			PeGC(HumanCnt),
 			PeGC(TimeoutCnt),
@@ -2220,32 +2233,32 @@
 //  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,Drbd_Parameter_Packet *partner)
+int drbd_md_compare(drbd_dev *mdev)
 {
 	int i;
-	u32 me,other;
+	u32 self,peer;
 
-	me=mdev->gen_cnt[Flags] & MDF_Consistent;
-	other=be32_to_cpu(partner->gen_cnt[Flags]) & MDF_Consistent;
-	if( me > other ) return 1;
-	if( me < other ) return -1;
+	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;
 
-	me=mdev->gen_cnt[Flags] & MDF_WasUpToDate;
-	other=be32_to_cpu(partner->gen_cnt[Flags]) & MDF_WasUpToDate;
-	if( me > other ) return 1;
-	if( me < other ) return -1;
+	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++) {
-		me=mdev->gen_cnt[i];
-		other=be32_to_cpu(partner->gen_cnt[i]);
-		if( me > other ) return 1;
-		if( me < other ) return -1;
+		self = mdev->gen_cnt[i];
+		peer = mdev->p_gen_cnt[i];
+		if( self > peer ) return 1;
+		if( self < peer ) return -1;
 	}
 
-	me=mdev->gen_cnt[Flags] & MDF_PrimaryInd;
-	other=be32_to_cpu(partner->gen_cnt[Flags]) & MDF_PrimaryInd;
-	if( me > other ) return 1;
-	if( me < other ) return -1;
+	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;
 }

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2005-01-14 20:02:24 UTC (rev 1721)
+++ trunk/drbd/drbd_receiver.c	2005-01-15 10:03:08 UTC (rev 1722)
@@ -303,8 +303,6 @@
 
 void drbd_put_ee(drbd_dev *mdev,struct Tl_epoch_entry *e)
 {
-	struct page* page;
-
 	MUST_HOLD(&mdev->ee_lock);
 
 	D_ASSERT(page_count(drbd_bio_get_page(&e->private_bio)) == 1);
@@ -317,9 +315,7 @@
 
 	if((mdev->ee_vacant * 2 > mdev->ee_in_use ) &&
 	   ( mdev->ee_vacant + mdev->ee_in_use > EE_MININUM) ) {
-		// FIXME cleanup: never returns NULL anymore
-		page=drbd_free_ee(mdev,&mdev->free_ee);
-		if( page ) __free_page(page);
+		__free_page(drbd_free_ee(mdev,&mdev->free_ee));
 	}
 	if(mdev->ee_in_use == 0) {
 		while( mdev->ee_vacant > EE_MININUM ) {
@@ -709,7 +705,11 @@
 
 	drbd_thread_start(&mdev->asender);
 
-	drbd_send_param(mdev,0);
+	drbd_send_protocol(mdev);
+	drbd_send_sync_param(mdev,&mdev->sync_conf);
+	drbd_send_sizes(mdev);
+	drbd_send_gen_cnt(mdev);
+	drbd_send_state(mdev);
 
 	return 1;
 }
@@ -1152,42 +1152,15 @@
 	return TRUE;
 }
 
-STATIC int receive_SyncParam(drbd_dev *mdev,Drbd_Header *h)
-{
-	int ok = TRUE;
-	Drbd_SyncParam_Packet *p = (Drbd_SyncParam_Packet*)h;
-
-	// FIXME move into helper
-	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
-
-	if (drbd_recv(mdev, h->payload, h->length) != h->length)
-		return FALSE;
-
-	// XXX harmless race with ioctl ...
-	mdev->sync_conf.rate      = be32_to_cpu(p->rate);
-	mdev->sync_conf.use_csums = be32_to_cpu(p->use_csums);
-	mdev->sync_conf.skip      = be32_to_cpu(p->skip);
-	drbd_alter_sg(mdev, be32_to_cpu(p->group));
-
-	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;
-}
-
 /* 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)
+STATIC drbd_conns_t drbd_sync_handshake(drbd_dev *mdev)
 {
 	int have_good,sync;
 	drbd_conns_t rv = conn_mask;
 
-	have_good = drbd_md_compare(mdev,p);
+	have_good = drbd_md_compare(mdev);
 
 	if(have_good==0) {
 		if (drbd_md_test_flag(mdev,MDF_PrimaryInd)) {
@@ -1211,7 +1184,7 @@
 		sync=1;
 	}
 
-	drbd_dump_md(mdev,p,0);
+	drbd_dump_md(mdev,0);
 	// INFO("have_good=%d sync=%d\n", have_good, sync);
 
 	if (have_good > 0 && mdev->state.s.disk <= Inconsistent ) {
@@ -1222,8 +1195,7 @@
 		drbd_thread_stop_nowait(&mdev->receiver);
 		return conn_mask;
 	}
-	if (have_good < 0 &&
-	    !(be32_to_cpu(p->gen_cnt[Flags]) & MDF_Consistent) ) {
+	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");
@@ -1237,10 +1209,10 @@
 	}
 
 	if( sync ) {
-		if( mdev->peer_uuid != be64_to_cpu(p->uuid) ) {
+		if( test_bit(UUID_CHANGED,&mdev->flags) ) {
 			WARN("Peer presented a new UUID -> full sync.\n");
-			mdev->peer_uuid = be64_to_cpu(p->uuid);
 			drbd_bm_set_all(mdev);
+			clear_bit(UUID_CHANGED, &mdev->flags);
 		}
 
 		if(have_good == 1) {
@@ -1294,46 +1266,20 @@
 		/* Sync-Target has to adopt source's gen_cnt. */
 		int i;
 		for(i=HumanCnt;i<GEN_CNT_SIZE;i++) {
-			mdev->gen_cnt[i]=be32_to_cpu(p->gen_cnt[i]);
+			mdev->gen_cnt[i]=mdev->p_gen_cnt[i];
 		}
 	}
 	return rv;
 }
 
-STATIC int receive_param(drbd_dev *mdev, Drbd_Header *h)
+STATIC int receive_protocol(drbd_dev *mdev, Drbd_Header *h)
 {
-	Drbd_Parameter_Packet *p = (Drbd_Parameter_Packet*)h;
-	drbd_conns_t nconn;
-	drbd_state_t ns,peer_state;
-	int consider_sync,rv;
-	sector_t p_size;
+	Drbd_Protocol_Packet *p = (Drbd_Protocol_Packet*)h;
 
-	if (h->length != (sizeof(*p)-sizeof(*h))) {
-		ERR("Incompatible packet size of Parameter packet!\n");
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
-		return FALSE;
-	}
-
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
 	if (drbd_recv(mdev, h->payload, h->length) != h->length)
 		return FALSE;
 
-	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));
-		drbd_force_state(mdev,NS(conn,StandAlone));
-		drbd_thread_stop_nowait(&mdev->receiver);
-		return FALSE;
-	}
-
-	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));
-		drbd_force_state(mdev,NS(conn,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) {
@@ -1352,11 +1298,47 @@
 		return FALSE;
 	}
 
-	p_size=be64_to_cpu(p->p_size);
+	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;
+}
+
+STATIC int receive_SyncParam(drbd_dev *mdev,Drbd_Header *h)
+{
+	int ok = TRUE;
+	Drbd_SyncParam_Packet *p = (Drbd_SyncParam_Packet*)h;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	// XXX harmless race with ioctl ...
+	mdev->sync_conf.rate      = be32_to_cpu(p->rate);
+	mdev->sync_conf.use_csums = be32_to_cpu(p->use_csums);
+	mdev->sync_conf.skip      = be32_to_cpu(p->skip);
+	drbd_alter_sg(mdev, be32_to_cpu(p->group));
+
+	return ok;
+}
+
+STATIC int receive_sizes(drbd_dev *mdev, Drbd_Header *h)
+{
+	Drbd_Sizes_Packet *p = (Drbd_Sizes_Packet*)h;
+	sector_t p_size;
+	drbd_conns_t nconn;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	// TODO also take o->c_size into account!
+
+	p_size=be64_to_cpu(p->d_size);
+
 	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");
 		drbd_force_state(mdev,NS(conn,StandAlone));
 		drbd_thread_stop_nowait(&mdev->receiver);
@@ -1365,52 +1347,72 @@
 
 	drbd_bm_lock(mdev); // {
 	mdev->p_size=p_size;
-
-	set_bit(MD_DIRTY,&mdev->flags); // we are changing state!
-
 	if( mdev->lo_usize != be64_to_cpu(p->u_size) ) {
 		mdev->lo_usize = be64_to_cpu(p->u_size);
 		INFO("Peer sets u_size to %lu KB\n",
 		     (unsigned long)mdev->lo_usize);
 	}
+	drbd_determin_dev_size(mdev);
+	drbd_bm_unlock(mdev); // }
+	
+	if (mdev->p_gen_cnt) {
+		nconn=drbd_sync_handshake(mdev);
+		kfree(mdev->p_gen_cnt);
+		mdev->p_gen_cnt = 0;
+		if(nconn == conn_mask) return FALSE;
 
-/*lge:
- * FIXME
- * please get the order of tests (re)settings for consider_sync
- * right, and comment them!
- */
+		if(drbd_request_state(mdev,NS(conn,nconn)) <= 0) {
+			drbd_force_state(mdev,NS(conn,StandAlone));
+			drbd_thread_stop_nowait(&mdev->receiver);
+			return FALSE;
+		}
+	}
 
-	consider_sync = ((nconn=mdev->state.s.conn) == WFReportParams);
-	if(drbd_determin_dev_size(mdev)) consider_sync=0;
+	return TRUE;
+}
 
-	if(mdev->state.s.disk==Diskless) consider_sync=0;
+STATIC int receive_gen_cnt(drbd_dev *mdev, Drbd_Header *h)
+{
+	Drbd_GenCnt_Packet *p = (Drbd_GenCnt_Packet*)h;
+	u32 *p_gen_cnt;
+	int i;
 
-	drbd_bm_unlock(mdev); // }
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
 
-	if(be32_to_cpu(p->flags)&1) {
-		consider_sync=1;
-		drbd_send_param(mdev,2);
+	p_gen_cnt = kmalloc(sizeof(u32)*GEN_CNT_SIZE, GFP_KERNEL);
+
+	for (i = Flags; i < GEN_CNT_SIZE; i++) {
+		p_gen_cnt[i] = be32_to_cpu(p->gen_cnt[i]);
 	}
-	if(be32_to_cpu(p->flags)&2) consider_sync=1;
 
-	// XXX harmless race with ioctl ...
-	mdev->sync_conf.rate  =
-		max_t(int,mdev->sync_conf.rate, be32_to_cpu(p->sync_rate));
+	if ( mdev->p_gen_cnt ) kfree(mdev->p_gen_cnt);
+	mdev->p_gen_cnt = p_gen_cnt;
 
-	// if one of them wants to skip, both of them should skip.
-	mdev->sync_conf.skip  =
-		mdev->sync_conf.skip != 0 || p->skip_sync != 0;
-	mdev->sync_conf.group =
-		min_t(int,mdev->sync_conf.group,be32_to_cpu(p->sync_group));
+	return TRUE;
+}
 
-	if (mdev->state.s.conn == WFReportParams) {
-		INFO("Connection established.\n");
-	}
 
-	nconn=Connected;
-	if (consider_sync) {
-		if ((nconn=drbd_sync_handshake(mdev,p))==conn_mask) 
-			return FALSE;
+STATIC int receive_state(drbd_dev *mdev, Drbd_Header *h)
+{
+	Drbd_State_Packet *p = (Drbd_State_Packet*)h;
+	drbd_conns_t nconn;
+	drbd_state_t ns,peer_state;
+	int rv;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	nconn = mdev->state.s.conn;
+	if (nconn == WFReportParams ) nconn = Connected;
+
+	if (mdev->p_gen_cnt) {
+		nconn=drbd_sync_handshake(mdev);
+		kfree(mdev->p_gen_cnt);
+		mdev->p_gen_cnt = 0;
+		if(nconn == conn_mask) return FALSE;
 	}
 
 	peer_state.i = be32_to_cpu(p->state);
@@ -1435,6 +1437,7 @@
 	return TRUE;
 }
 
+
 /* Since we are processing the bitfild from lower addresses to higher,
    it does not matter if the process it in 32 bit chunks or 64 bit
    chunks as long as it is little endian. (Understand it as byte stream,
@@ -1591,7 +1594,6 @@
 	[WriteAck]         = NULL, //receive_WriteAck,
 	[Barrier]          = receive_Barrier,
 	[BarrierAck]       = NULL, //receive_BarrierAck,
-	[ReportParams]     = receive_param,
 	[ReportBitMap]     = receive_bitmap,
 	[Ping]             = NULL, //receive_Ping,
 	[PingAck]          = NULL, //receive_PingAck,
@@ -1601,6 +1603,10 @@
 	[DataRequest]      = receive_DataRequest,
 	[RSDataRequest]    = receive_DataRequest, //receive_RSDataRequest,
 	[SyncParam]        = receive_SyncParam,
+	[ReportProtocol]   = receive_protocol,
+	[ReportGenCnt]     = receive_gen_cnt,
+	[ReportSizes]      = receive_sizes,
+	[ReportState]      = receive_state,
 };
 
 static drbd_cmd_handler_f *drbd_cmd_handler = drbd_default_handler;
@@ -1629,10 +1635,6 @@
 			    header->command, header->length);
 			break;
 		}
-		if (mdev->state.s.conn == WFReportParams && header->command != ReportParams) {
-			ERR("received %s packet while WFReportParams!?\n",
-					cmdname(header->command));
-		}
 		if (unlikely(!handler(mdev,header))) {
 			ERR("error receiving %s, l: %d!\n",
 			    cmdname(header->command), header->length);
@@ -1797,11 +1799,7 @@
 	rv = drbd_recv_header(mdev,&p->head);
 	if (!rv) return 0;
 
-	if (p->head.command == ReportParams) {
-		ERR("expected HandShake packet, received ReportParams...\n");
-		ERR("peer probaly runs some incompatible 0.7 -preX version\n");
-		return 0;
-	} else if (p->head.command != HandShake) {
+	if (p->head.command != HandShake) {
 		ERR( "expected HandShake packet, received: %s (0x%04x)\n",
 		     cmdname(p->head.command), p->head.command );
 		return 0;



More information about the drbd-cvs mailing list