[DRBD-cvs] svn commit by phil - r2343 - trunk/drbd - Another execellent bug report by Simon...

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Tue Aug 8 17:00:55 CEST 2006


Author: phil
Date: 2006-08-08 17:00:53 +0200 (Tue, 08 Aug 2006)
New Revision: 2343

Modified:
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
Log:
Another execellent bug report by Simon...
http://lists.linbit.com/pipermail/drbd-dev/2006-August/000380.html


Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-08-08 13:28:34 UTC (rev 2342)
+++ trunk/drbd/drbd_int.h	2006-08-08 15:00:53 UTC (rev 2343)
@@ -880,6 +880,10 @@
 			   u32 set_size);
 extern int drbd_send_ack(drbd_dev *mdev, Drbd_Packet_Cmd cmd,
 			 struct Tl_epoch_entry *e);
+extern int drbd_send_ack_rp(drbd_dev *mdev, Drbd_Packet_Cmd cmd, 
+			    Drbd_BlockRequest_Packet *rp);
+extern int drbd_send_ack_dp(drbd_dev *mdev, Drbd_Packet_Cmd cmd, 
+			    Drbd_Data_Packet *dp);
 extern int _drbd_send_page(drbd_dev *mdev, struct page *page,
 			   int offset, size_t size);
 extern int drbd_send_block(drbd_dev *mdev, Drbd_Packet_Cmd cmd,

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-08-08 13:28:34 UTC (rev 2342)
+++ trunk/drbd/drbd_main.c	2006-08-08 15:00:53 UTC (rev 2343)
@@ -1497,31 +1497,52 @@
 	return ok;
 }
 
-
-int drbd_send_ack(drbd_dev *mdev, Drbd_Packet_Cmd cmd, struct Tl_epoch_entry *e)
+/** 
+ * _drbd_send_ack:
+ * This helper function expects the sector and block_id parameter already
+ * in big endian!
+ */ 
+static int _drbd_send_ack(drbd_dev *mdev, Drbd_Packet_Cmd cmd, 
+			  sector_t sector,
+			  unsigned int blksize,
+			  u64 block_id)
 {
 	int ok;
 	Drbd_BlockAck_Packet p;
 
-	p.sector   = cpu_to_be64(drbd_ee_get_sector(e));
-	p.block_id = e->block_id;
-	p.blksize  = cpu_to_be32(drbd_ee_get_size(e));
-/*
- * FIXME kernel source <= 2.6.8 don't have atomic_add_return!
- */
-#if 0
-#warning "YES I KNOW. JUST SO IT COMPILES NOW."
-	atomic_inc(&mdev->packet_seq);
-	p.seq_num = atomic_read(&mdev->packet_seq);
-#else
+	p.sector   = sector;
+	p.block_id = block_id;
+	p.blksize  = blksize;
 	p.seq_num  = cpu_to_be32(atomic_add_return(1,&mdev->packet_seq));
-#endif
 
 	if (!mdev->meta.socket || mdev->state.conn < Connected) return FALSE;
 	ok=drbd_send_cmd(mdev,USE_META_SOCKET,cmd,(Drbd_Header*)&p,sizeof(p));
 	return ok;
 }
 
+int drbd_send_ack_dp(drbd_dev *mdev, Drbd_Packet_Cmd cmd, 
+		     Drbd_Data_Packet *dp)
+{
+	const int header_size = sizeof(Drbd_Data_Packet) - sizeof(Drbd_Header);
+	int data_size  = ((Drbd_Header*)dp)->length - header_size;
+
+	return _drbd_send_ack(mdev,cmd,dp->sector,data_size,dp->block_id);
+}
+
+int drbd_send_ack_rp(drbd_dev *mdev, Drbd_Packet_Cmd cmd, 
+		     Drbd_BlockRequest_Packet *rp)
+{
+	return _drbd_send_ack(mdev,cmd,rp->sector,rp->blksize,rp->block_id);
+}
+
+int drbd_send_ack(drbd_dev *mdev, Drbd_Packet_Cmd cmd, struct Tl_epoch_entry *e)
+{
+	return _drbd_send_ack(mdev,cmd,
+			      cpu_to_be64(drbd_ee_get_sector(e)),
+			      cpu_to_be32(drbd_ee_get_size(e)),
+			      e->block_id);
+}
+
 int drbd_send_drequest(drbd_dev *mdev, int cmd,
 		       sector_t sector,int size, u64 block_id)
 {

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-08-08 13:28:34 UTC (rev 2342)
+++ trunk/drbd/drbd_receiver.c	2006-08-08 15:00:53 UTC (rev 2343)
@@ -988,18 +988,14 @@
 	struct Tl_epoch_entry *e;
 
 	e = read_in_block(mdev,sector,data_size);
-	if(!e) return FALSE;
+	if(!e) {
+		dec_local(mdev);
+		return FALSE;
+	}
 
 	dec_rs_pending(mdev);
 
 	e->block_id = ID_SYNCER;
-	if(!inc_local(mdev)) {
-		if (DRBD_ratelimit(5*HZ,5))
-			ERR("Can not write resync data to local disk.\n");
-		drbd_send_ack(mdev,NegAck,e);
-		drbd_free_ee(mdev,e);
-		return TRUE;
-	}
 
 	drbd_ee_prepare_write(mdev,e);
 	e->w.cb     = e_end_resync_block;
@@ -1079,6 +1075,13 @@
 	sector = be64_to_cpu(p->sector);
 	D_ASSERT(p->block_id == ID_SYNCER);
 
+	if(!inc_local(mdev)) {
+		if (DRBD_ratelimit(5*HZ,5))
+			ERR("Can not write resync data to local disk.\n");
+		drbd_send_ack_dp(mdev,NegAck,p);
+		return TRUE;
+	}
+
 	ok = recv_resync_read(mdev,sector,data_size);
 
 	return ok;
@@ -1221,18 +1224,20 @@
 	if (drbd_recv(mdev, h->payload, header_size) != header_size)
 		return FALSE;
 
-	sector = be64_to_cpu(p->sector);
-	e = read_in_block(mdev,sector,data_size);
-	if (!e) return FALSE;
-
 	if(!inc_local(mdev)) {
 		if (DRBD_ratelimit(5*HZ,5))
 			ERR("Can not write mirrored data block to local disk.\n");
-		drbd_send_ack(mdev,NegAck,e);
-		rv = TRUE;
-		goto out1;
+		drbd_send_ack_dp(mdev,NegAck,p);
+		return TRUE;
 	}
 
+	sector = be64_to_cpu(p->sector);
+	e = read_in_block(mdev,sector,data_size);
+	if (!e) {
+		dec_local(mdev);
+		return FALSE;
+	}
+
 	e->block_id = p->block_id; // no meaning on this side, e* on partner
 	drbd_ee_prepare_write(mdev, e);
 	e->w.cb     = e_end_block;
@@ -1399,7 +1404,6 @@
 	 * but we drop the connection anyways, so we don't have a chance to
 	 * receive a barrier... atomic_inc(&mdev->epoch_size); */
 	dec_local(mdev);
- out1:
 	drbd_free_ee(mdev,e);
 	return rv;
 }
@@ -1431,23 +1435,25 @@
 		return FALSE;
 	}
 
+	if(!inc_local(mdev) || mdev->state.disk < UpToDate ) {
+		if (DRBD_ratelimit(5*HZ,5))
+			ERR("Can not satisfy peer's read request, no local data.\n");
+		drbd_send_ack_rp(mdev,h->command == DataRequest ? NegDReply :
+				 NegRSDReply ,p);
+		return TRUE;
+	}
+
 	e = drbd_alloc_ee(mdev,sector,size,GFP_KERNEL);
-	if (!e) return FALSE;
+	if (!e) {
+		dec_local(mdev);
+		return FALSE;
+	}
 
 	e->block_id = p->block_id; // no meaning on this side, pr* on partner
 	spin_lock_irq(&mdev->ee_lock);
 	list_add(&e->w.list,&mdev->read_ee);
 	spin_unlock_irq(&mdev->ee_lock);
 
-	if(!inc_local(mdev) || mdev->state.disk < UpToDate ) {
-		if (DRBD_ratelimit(5*HZ,5))
-			ERR("Can not satisfy peer's read request, no local data.\n");
-		drbd_send_ack(mdev,h->command == DataRequest ? NegDReply :
-			      NegRSDReply ,e);
-		drbd_free_ee(mdev,e);
-		return TRUE;
-	}
-
 	drbd_ee_prepare_read(mdev,e);
 
 	switch (h->command) {



More information about the drbd-cvs mailing list