[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