[DRBD-cvs] drbd by phil; In the asender this expression fired ERR...
drbd-user@lists.linbit.com
drbd-user@lists.linbit.com
Sat, 17 Jan 2004 22:18:38 +0100 (CET)
DRBD CVS committal
Author : phil
Module : drbd
Dir : drbd/drbd
Modified Files:
Tag: rel-0_7-branch
drbd_receiver.c
Log Message:
In the asender this expression fired
ERR_IF (h->length != expect) goto err;
when a signal occured before a packet was received in full length.
In the process of fixing it, I did the jump-table-like approch.
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_receiver.c,v
retrieving revision 1.97.2.86
retrieving revision 1.97.2.87
diff -u -3 -r1.97.2.86 -r1.97.2.87
--- drbd_receiver.c 16 Jan 2004 13:26:43 -0000 1.97.2.86
+++ drbd_receiver.c 17 Jan 2004 21:18:38 -0000 1.97.2.87
@@ -776,37 +776,6 @@
return TRUE;
}
-STATIC int process_BlockAck(drbd_dev *mdev, Drbd_Header* h)
-{
- drbd_request_t *req;
- Drbd_BlockAck_Packet *p = (Drbd_BlockAck_Packet*)h;
-
- if( is_syncer_blk(mdev,p->block_id)) {
- drbd_set_in_sync(mdev,
- be64_to_cpu(p->sector),
- be32_to_cpu(p->blksize));
- } else {
- req=(drbd_request_t*)(long)p->block_id;
-
- ERR_IF ((unsigned long)req <= 1) return FALSE;
- ERR_IF (!VALID_POINTER(req)) return FALSE;
-
- drbd_end_req(req, RQ_DRBD_SENT, 1, be64_to_cpu(p->sector) );
- }
- /*WARN("BlockAck: %lx %lx %x\n",
- (long) p->block_id,
- (long) be64_to_cpu(p->sector),
- be32_to_cpu(p->blksize));*/
-
- // TODO: Make sure that the block is in an active epoch!!
- if(mdev->conf.wire_protocol != DRBD_PROT_A ||
- is_syncer_blk(mdev,p->block_id)) {
- dec_pending(mdev,HERE);
- }
-
- return TRUE;
-}
-
STATIC int receive_Barrier(drbd_dev *mdev, Drbd_Header* h)
{
int rv;
@@ -843,14 +812,6 @@
return TRUE;
}
-STATIC void process_BarrierAck(drbd_dev *mdev, Drbd_Header* h)
-{
- Drbd_BarrierAck_Packet *p = (Drbd_BarrierAck_Packet*)h;
-
- tl_release(mdev,p->barrier,be32_to_cpu(p->set_size));
- dec_pending(mdev,HERE);
-}
-
STATIC struct Tl_epoch_entry *
read_in_block(drbd_dev *mdev,int data_size)
{
@@ -1712,18 +1673,84 @@
return rv;
}
+STATIC int got_Ping(drbd_dev *mdev, Drbd_Header* h)
+{
+ return drbd_send_ping_ack(mdev);
+
+}
+
+STATIC int got_PingAck(drbd_dev *mdev, Drbd_Header* h)
+{
+ // restore idle timeout
+ mdev->meta.socket->sk->rcvtimeo = mdev->conf.ping_int*HZ;
+
+ return TRUE;
+}
+
+STATIC int got_BlockAck(drbd_dev *mdev, Drbd_Header* h)
+{
+ drbd_request_t *req;
+ Drbd_BlockAck_Packet *p = (Drbd_BlockAck_Packet*)h;
+ sector_t sector = be64_to_cpu(p->sector);
+ int blksize = be32_to_cpu(p->blksize);
+
+ if( is_syncer_blk(mdev,p->block_id)) {
+ drbd_set_in_sync(mdev,sector,blksize);
+ } else {
+ req=(drbd_request_t*)(long)p->block_id;
+
+ ERR_IF (!VALID_POINTER(req)) return FALSE;
+
+ drbd_end_req(req, RQ_DRBD_SENT, 1, sector);
+ }
+ /*WARN("BlockAck: %lx %lx %x\n",
+ (long) p->block_id,
+ (long) be64_to_cpu(p->sector),
+ be32_to_cpu(p->blksize));*/
+
+ // TODO: Make sure that the block is in an active epoch!!
+ if(mdev->conf.wire_protocol != DRBD_PROT_A ||
+ is_syncer_blk(mdev,p->block_id)) {
+ dec_pending(mdev,HERE);
+ }
+
+ return TRUE;
+}
+
+STATIC int got_BarrierAck(drbd_dev *mdev, Drbd_Header* h)
+{
+ Drbd_BarrierAck_Packet *p = (Drbd_BarrierAck_Packet*)h;
+
+ tl_release(mdev,p->barrier,be32_to_cpu(p->set_size));
+ dec_pending(mdev,HERE);
+
+ return TRUE;
+}
+
+struct asender_cmd {
+ size_t pkt_size;
+ int (*process)(drbd_dev *mdev, Drbd_Header* h);
+};
+
int drbd_asender(struct Drbd_thread *thi)
{
- // shortcuts
drbd_dev *mdev = thi->mdev;
Drbd_Header *h = &mdev->meta.rbuf.head;
unsigned long flags = 0;
- int rv;
+ int rv,len;
void *buf = h;
int received = 0;
int expect = sizeof(Drbd_Header);
+ int cmd = -1;
+ static struct asender_cmd asender_tbl[] = {
+ [Ping] ={ sizeof(Drbd_Header), got_Ping },
+ [PingAck] ={ sizeof(Drbd_Header), got_PingAck },
+ [RecvAck] ={ sizeof(Drbd_BlockAck_Packet), got_BlockAck },
+ [WriteAck] ={ sizeof(Drbd_BlockAck_Packet), got_BlockAck },
+ [BarrierAck]={ sizeof(Drbd_BarrierAck_Packet),got_BarrierAck },
+ };
sprintf(current->comm, "drbd%d_asender", (int)(mdev-drbd_conf));
@@ -1745,7 +1772,8 @@
if (!drbd_process_ee(mdev,&mdev->done_ee)) goto err;
- rv = drbd_recv_short(mdev,mdev->meta.socket,buf,expect);
+ rv = drbd_recv_short(mdev,mdev->meta.socket,buf,
+ expect-received);
/* Note:
* -EINTR (on meta) we got a signal
@@ -1759,7 +1787,6 @@
*/
if (likely(rv > 0)) {
received += rv;
- expect -= rv;
buf += rv;
} else if (rv == 0) {
ERR("meta connection shut down by peer.\n");
@@ -1767,79 +1794,38 @@
} else if (rv == -EAGAIN) {
set_bit(SEND_PING,&mdev->flags);
continue;
- } else if (rv != -EINTR) {
- // if (rv != -ECONNRESET)
- ERR("sock_recvmsg returned %d\n", rv);
- goto err;
- }
-
- if (expect) {
- // rv == -EINTR || rv < expect
+ } else if (rv == -EINTR) {
LOCK_SIGMASK(current,flags);
sigemptyset(¤t->pending.signal);
RECALC_SIGPENDING(current);
UNLOCK_SIGMASK(current,flags);
+ // Do something on signal ??
continue;
+ } else {
+ ERR("sock_recvmsg returned %d\n", rv);
+ goto err;
}
- // MAYBE use jump table
-
- if (received == sizeof(Drbd_Header)) {
- h->command = be16_to_cpu(h->command);
- h->length = be16_to_cpu(h->length);
+ if (received == expect && cmd == -1 ) {
+ cmd = be16_to_cpu(h->command);
+ len = be16_to_cpu(h->length);
if (unlikely( h->magic != BE_DRBD_MAGIC )) {
ERR("magic?? m: 0x%lx c: %d l: %d\n",
(long)be32_to_cpu(h->magic),
h->command, h->length);
goto err;
}
+ expect = asender_tbl[cmd].pkt_size;
}
-
- /*
- * If packet command numbers were ordered by packet size,
- * we could just say something like
- * if (h->command > [last command without payload data])
- * { expect = whatever; continue; }
- */
-
- switch (h->command) {
- case Ping:
- ERR_IF(!drbd_send_ping_ack(mdev))
- goto err;
- // If partner pings me, maybe its time to kick IO
- //run_task_queue(&tq_disk);
- break;
- case PingAck:
- // restore idle timeout
- mdev->meta.socket->sk->rcvtimeo =
- mdev->conf.ping_int*HZ;
- break;
- case RecvAck:
- case WriteAck:
- if (received != sizeof(Drbd_BlockAck_Packet)) {
- expect = sizeof(Drbd_BlockAck_Packet)
- - received;
- ERR_IF (h->length != expect) goto err;
- continue;
- }
- ERR_IF (!process_BlockAck(mdev,h)) goto err;
- break;
- case BarrierAck:
- if (received != sizeof(Drbd_Barrier_Packet)) {
- expect = sizeof(Drbd_Barrier_Packet)
- - received;
- ERR_IF (h->length != expect) goto err;
- continue;
- }
- ERR_IF (mdev->state != Primary) goto err;
- process_BarrierAck(mdev,h);
- break;
- default:
- D_ASSERT(0);
+ if(received == expect) {
+ D_ASSERT(cmd != -1);
+ if(!asender_tbl[cmd].process(mdev,h)) goto err;
+
+ buf = h;
+ received = 0;
+ expect = sizeof(Drbd_Header);
+ cmd = -1;
}
- buf = h;
- received = 0;
- expect = sizeof(Drbd_Header);
} //while
if(0) {