diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-03-30 06:54:42 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:45:09 -0500 |
commit | e658983af6e62304be785cd6b0ae756723057395 (patch) | |
tree | 6dd2e2c85c704fb353d02feeb25cfc44613405e1 /drivers | |
parent | 50d0b1ad78b99aa776c3ddf9b1d45163fff435b9 (diff) |
drbd: Remove headers from on-the-wire data structures (struct p_*)
Prepare the introduction of the protocol 100 headers. The actual protocol
header is removed for the packet declarations. I.e. allow us to use the
packets with different headers.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 45 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 45 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 172 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_worker.c | 2 |
4 files changed, 110 insertions, 154 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index cb16783e78df..6d55bb75a081 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -307,32 +307,8 @@ struct p_header95 { | |||
307 | u32 length; /* Use only 24 bits of that. Ignore the highest 8 bit. */ | 307 | u32 length; /* Use only 24 bits of that. Ignore the highest 8 bit. */ |
308 | } __packed; | 308 | } __packed; |
309 | 309 | ||
310 | struct p_header { | ||
311 | union { | ||
312 | struct p_header80 h80; | ||
313 | struct p_header95 h95; | ||
314 | }; | ||
315 | u8 payload[0]; | ||
316 | }; | ||
317 | |||
318 | extern unsigned int drbd_header_size(struct drbd_tconn *tconn); | 310 | extern unsigned int drbd_header_size(struct drbd_tconn *tconn); |
319 | 311 | ||
320 | /* | ||
321 | * short commands, packets without payload, plain p_header: | ||
322 | * P_PING | ||
323 | * P_PING_ACK | ||
324 | * P_BECOME_SYNC_TARGET | ||
325 | * P_BECOME_SYNC_SOURCE | ||
326 | * P_UNPLUG_REMOTE | ||
327 | */ | ||
328 | |||
329 | /* | ||
330 | * commands with out-of-struct payload: | ||
331 | * P_BITMAP (no additional fields) | ||
332 | * P_DATA, P_DATA_REPLY (see p_data) | ||
333 | * P_COMPRESSED_BITMAP (see receive_compressed_bitmap) | ||
334 | */ | ||
335 | |||
336 | /* these defines must not be changed without changing the protocol version */ | 312 | /* these defines must not be changed without changing the protocol version */ |
337 | #define DP_HARDBARRIER 1 /* depricated */ | 313 | #define DP_HARDBARRIER 1 /* depricated */ |
338 | #define DP_RW_SYNC 2 /* equals REQ_SYNC */ | 314 | #define DP_RW_SYNC 2 /* equals REQ_SYNC */ |
@@ -343,7 +319,6 @@ extern unsigned int drbd_header_size(struct drbd_tconn *tconn); | |||
343 | #define DP_DISCARD 64 /* equals REQ_DISCARD */ | 319 | #define DP_DISCARD 64 /* equals REQ_DISCARD */ |
344 | 320 | ||
345 | struct p_data { | 321 | struct p_data { |
346 | struct p_header head; | ||
347 | u64 sector; /* 64 bits sector number */ | 322 | u64 sector; /* 64 bits sector number */ |
348 | u64 block_id; /* to identify the request in protocol B&C */ | 323 | u64 block_id; /* to identify the request in protocol B&C */ |
349 | u32 seq_num; | 324 | u32 seq_num; |
@@ -359,7 +334,6 @@ struct p_data { | |||
359 | * P_DATA_REQUEST, P_RS_DATA_REQUEST | 334 | * P_DATA_REQUEST, P_RS_DATA_REQUEST |
360 | */ | 335 | */ |
361 | struct p_block_ack { | 336 | struct p_block_ack { |
362 | struct p_header head; | ||
363 | u64 sector; | 337 | u64 sector; |
364 | u64 block_id; | 338 | u64 block_id; |
365 | u32 blksize; | 339 | u32 blksize; |
@@ -367,7 +341,6 @@ struct p_block_ack { | |||
367 | } __packed; | 341 | } __packed; |
368 | 342 | ||
369 | struct p_block_req { | 343 | struct p_block_req { |
370 | struct p_header head; | ||
371 | u64 sector; | 344 | u64 sector; |
372 | u64 block_id; | 345 | u64 block_id; |
373 | u32 blksize; | 346 | u32 blksize; |
@@ -384,7 +357,6 @@ struct p_block_req { | |||
384 | */ | 357 | */ |
385 | 358 | ||
386 | struct p_connection_features { | 359 | struct p_connection_features { |
387 | struct p_header head; /* Note: vnr will be ignored */ | ||
388 | u32 protocol_min; | 360 | u32 protocol_min; |
389 | u32 feature_flags; | 361 | u32 feature_flags; |
390 | u32 protocol_max; | 362 | u32 protocol_max; |
@@ -396,22 +368,18 @@ struct p_connection_features { | |||
396 | u32 _pad; | 368 | u32 _pad; |
397 | u64 reserverd[7]; | 369 | u64 reserverd[7]; |
398 | } __packed; | 370 | } __packed; |
399 | /* 80 bytes, FIXED for the next century */ | ||
400 | 371 | ||
401 | struct p_barrier { | 372 | struct p_barrier { |
402 | struct p_header head; | ||
403 | u32 barrier; /* barrier number _handle_ only */ | 373 | u32 barrier; /* barrier number _handle_ only */ |
404 | u32 pad; /* to multiple of 8 Byte */ | 374 | u32 pad; /* to multiple of 8 Byte */ |
405 | } __packed; | 375 | } __packed; |
406 | 376 | ||
407 | struct p_barrier_ack { | 377 | struct p_barrier_ack { |
408 | struct p_header head; | ||
409 | u32 barrier; | 378 | u32 barrier; |
410 | u32 set_size; | 379 | u32 set_size; |
411 | } __packed; | 380 | } __packed; |
412 | 381 | ||
413 | struct p_rs_param { | 382 | struct p_rs_param { |
414 | struct p_header head; | ||
415 | u32 rate; | 383 | u32 rate; |
416 | 384 | ||
417 | /* Since protocol version 88 and higher. */ | 385 | /* Since protocol version 88 and higher. */ |
@@ -419,7 +387,6 @@ struct p_rs_param { | |||
419 | } __packed; | 387 | } __packed; |
420 | 388 | ||
421 | struct p_rs_param_89 { | 389 | struct p_rs_param_89 { |
422 | struct p_header head; | ||
423 | u32 rate; | 390 | u32 rate; |
424 | /* protocol version 89: */ | 391 | /* protocol version 89: */ |
425 | char verify_alg[SHARED_SECRET_MAX]; | 392 | char verify_alg[SHARED_SECRET_MAX]; |
@@ -427,7 +394,6 @@ struct p_rs_param_89 { | |||
427 | } __packed; | 394 | } __packed; |
428 | 395 | ||
429 | struct p_rs_param_95 { | 396 | struct p_rs_param_95 { |
430 | struct p_header head; | ||
431 | u32 rate; | 397 | u32 rate; |
432 | char verify_alg[SHARED_SECRET_MAX]; | 398 | char verify_alg[SHARED_SECRET_MAX]; |
433 | char csums_alg[SHARED_SECRET_MAX]; | 399 | char csums_alg[SHARED_SECRET_MAX]; |
@@ -443,7 +409,6 @@ enum drbd_conn_flags { | |||
443 | }; | 409 | }; |
444 | 410 | ||
445 | struct p_protocol { | 411 | struct p_protocol { |
446 | struct p_header head; | ||
447 | u32 protocol; | 412 | u32 protocol; |
448 | u32 after_sb_0p; | 413 | u32 after_sb_0p; |
449 | u32 after_sb_1p; | 414 | u32 after_sb_1p; |
@@ -457,17 +422,14 @@ struct p_protocol { | |||
457 | } __packed; | 422 | } __packed; |
458 | 423 | ||
459 | struct p_uuids { | 424 | struct p_uuids { |
460 | struct p_header head; | ||
461 | u64 uuid[UI_EXTENDED_SIZE]; | 425 | u64 uuid[UI_EXTENDED_SIZE]; |
462 | } __packed; | 426 | } __packed; |
463 | 427 | ||
464 | struct p_rs_uuid { | 428 | struct p_rs_uuid { |
465 | struct p_header head; | ||
466 | u64 uuid; | 429 | u64 uuid; |
467 | } __packed; | 430 | } __packed; |
468 | 431 | ||
469 | struct p_sizes { | 432 | struct p_sizes { |
470 | struct p_header head; | ||
471 | u64 d_size; /* size of disk */ | 433 | u64 d_size; /* size of disk */ |
472 | u64 u_size; /* user requested size */ | 434 | u64 u_size; /* user requested size */ |
473 | u64 c_size; /* current exported size */ | 435 | u64 c_size; /* current exported size */ |
@@ -477,18 +439,15 @@ struct p_sizes { | |||
477 | } __packed; | 439 | } __packed; |
478 | 440 | ||
479 | struct p_state { | 441 | struct p_state { |
480 | struct p_header head; | ||
481 | u32 state; | 442 | u32 state; |
482 | } __packed; | 443 | } __packed; |
483 | 444 | ||
484 | struct p_req_state { | 445 | struct p_req_state { |
485 | struct p_header head; | ||
486 | u32 mask; | 446 | u32 mask; |
487 | u32 val; | 447 | u32 val; |
488 | } __packed; | 448 | } __packed; |
489 | 449 | ||
490 | struct p_req_state_reply { | 450 | struct p_req_state_reply { |
491 | struct p_header head; | ||
492 | u32 retcode; | 451 | u32 retcode; |
493 | } __packed; | 452 | } __packed; |
494 | 453 | ||
@@ -503,14 +462,12 @@ struct p_drbd06_param { | |||
503 | } __packed; | 462 | } __packed; |
504 | 463 | ||
505 | struct p_discard { | 464 | struct p_discard { |
506 | struct p_header head; | ||
507 | u64 block_id; | 465 | u64 block_id; |
508 | u32 seq_num; | 466 | u32 seq_num; |
509 | u32 pad; | 467 | u32 pad; |
510 | } __packed; | 468 | } __packed; |
511 | 469 | ||
512 | struct p_block_desc { | 470 | struct p_block_desc { |
513 | struct p_header head; | ||
514 | u64 sector; | 471 | u64 sector; |
515 | u32 blksize; | 472 | u32 blksize; |
516 | u32 pad; /* to multiple of 8 Byte */ | 473 | u32 pad; /* to multiple of 8 Byte */ |
@@ -526,7 +483,6 @@ enum drbd_bitmap_code { | |||
526 | }; | 483 | }; |
527 | 484 | ||
528 | struct p_compressed_bm { | 485 | struct p_compressed_bm { |
529 | struct p_header head; | ||
530 | /* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code | 486 | /* (encoding & 0x0f): actual encoding, see enum drbd_bitmap_code |
531 | * (encoding & 0x80): polarity (set/unset) of first runlength | 487 | * (encoding & 0x80): polarity (set/unset) of first runlength |
532 | * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits | 488 | * ((encoding >> 4) & 0x07): pad_bits, number of trailing zero bits |
@@ -538,7 +494,6 @@ struct p_compressed_bm { | |||
538 | } __packed; | 494 | } __packed; |
539 | 495 | ||
540 | struct p_delay_probe93 { | 496 | struct p_delay_probe93 { |
541 | struct p_header head; | ||
542 | u32 seq_num; /* sequence number to match the two probe packets */ | 497 | u32 seq_num; /* sequence number to match the two probe packets */ |
543 | u32 offset; /* usecs the probe got sent after the reference time point */ | 498 | u32 offset; /* usecs the probe got sent after the reference time point */ |
544 | } __packed; | 499 | } __packed; |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 3ecbd4908cdc..b9dcc50135c4 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -703,27 +703,29 @@ unsigned int drbd_header_size(struct drbd_tconn *tconn) | |||
703 | return sizeof(struct p_header80); | 703 | return sizeof(struct p_header80); |
704 | } | 704 | } |
705 | 705 | ||
706 | static void prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size) | 706 | static unsigned int prepare_header80(struct p_header80 *h, enum drbd_packet cmd, int size) |
707 | { | 707 | { |
708 | h->magic = cpu_to_be32(DRBD_MAGIC); | 708 | h->magic = cpu_to_be32(DRBD_MAGIC); |
709 | h->command = cpu_to_be16(cmd); | 709 | h->command = cpu_to_be16(cmd); |
710 | h->length = cpu_to_be16(size); | 710 | h->length = cpu_to_be16(size); |
711 | return sizeof(struct p_header80); | ||
711 | } | 712 | } |
712 | 713 | ||
713 | static void prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size) | 714 | static unsigned int prepare_header95(struct p_header95 *h, enum drbd_packet cmd, int size) |
714 | { | 715 | { |
715 | h->magic = cpu_to_be16(DRBD_MAGIC_BIG); | 716 | h->magic = cpu_to_be16(DRBD_MAGIC_BIG); |
716 | h->command = cpu_to_be16(cmd); | 717 | h->command = cpu_to_be16(cmd); |
717 | h->length = cpu_to_be32(size); | 718 | h->length = cpu_to_be32(size); |
719 | return sizeof(struct p_header95); | ||
718 | } | 720 | } |
719 | 721 | ||
720 | static void prepare_header(struct drbd_tconn *tconn, int vnr, struct p_header *h, | 722 | static unsigned int prepare_header(struct drbd_tconn *tconn, int vnr, void *buffer, |
721 | enum drbd_packet cmd, int size) | 723 | enum drbd_packet cmd, int size) |
722 | { | 724 | { |
723 | if (tconn->agreed_pro_version >= 95) | 725 | if (tconn->agreed_pro_version >= 95) |
724 | prepare_header95(&h->h95, cmd, size); | 726 | return prepare_header95(buffer, cmd, size); |
725 | else | 727 | else |
726 | prepare_header80(&h->h80, cmd, size); | 728 | return prepare_header80(buffer, cmd, size); |
727 | } | 729 | } |
728 | 730 | ||
729 | void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock) | 731 | void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock) |
@@ -733,7 +735,7 @@ void *conn_prepare_command(struct drbd_tconn *tconn, struct drbd_socket *sock) | |||
733 | mutex_unlock(&sock->mutex); | 735 | mutex_unlock(&sock->mutex); |
734 | return NULL; | 736 | return NULL; |
735 | } | 737 | } |
736 | return sock->sbuf; | 738 | return sock->sbuf + drbd_header_size(tconn); |
737 | } | 739 | } |
738 | 740 | ||
739 | void *drbd_prepare_command(struct drbd_conf *mdev, struct drbd_socket *sock) | 741 | void *drbd_prepare_command(struct drbd_conf *mdev, struct drbd_socket *sock) |
@@ -758,8 +760,8 @@ static int __send_command(struct drbd_tconn *tconn, int vnr, | |||
758 | */ | 760 | */ |
759 | msg_flags = data ? MSG_MORE : 0; | 761 | msg_flags = data ? MSG_MORE : 0; |
760 | 762 | ||
761 | prepare_header(tconn, vnr, sock->sbuf, cmd, | 763 | header_size += prepare_header(tconn, vnr, sock->sbuf, cmd, |
762 | header_size - sizeof(struct p_header) + size); | 764 | header_size + size); |
763 | err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size, | 765 | err = drbd_send_all(tconn, sock->socket, sock->sbuf, header_size, |
764 | msg_flags); | 766 | msg_flags); |
765 | if (data && !err) | 767 | if (data && !err) |
@@ -797,7 +799,7 @@ int drbd_send_ping(struct drbd_tconn *tconn) | |||
797 | sock = &tconn->meta; | 799 | sock = &tconn->meta; |
798 | if (!conn_prepare_command(tconn, sock)) | 800 | if (!conn_prepare_command(tconn, sock)) |
799 | return -EIO; | 801 | return -EIO; |
800 | return conn_send_command(tconn, sock, P_PING, sizeof(struct p_header), NULL, 0); | 802 | return conn_send_command(tconn, sock, P_PING, 0, NULL, 0); |
801 | } | 803 | } |
802 | 804 | ||
803 | int drbd_send_ping_ack(struct drbd_tconn *tconn) | 805 | int drbd_send_ping_ack(struct drbd_tconn *tconn) |
@@ -807,7 +809,7 @@ int drbd_send_ping_ack(struct drbd_tconn *tconn) | |||
807 | sock = &tconn->meta; | 809 | sock = &tconn->meta; |
808 | if (!conn_prepare_command(tconn, sock)) | 810 | if (!conn_prepare_command(tconn, sock)) |
809 | return -EIO; | 811 | return -EIO; |
810 | return conn_send_command(tconn, sock, P_PING_ACK, sizeof(struct p_header), NULL, 0); | 812 | return conn_send_command(tconn, sock, P_PING_ACK, 0, NULL, 0); |
811 | } | 813 | } |
812 | 814 | ||
813 | int drbd_send_sync_param(struct drbd_conf *mdev) | 815 | int drbd_send_sync_param(struct drbd_conf *mdev) |
@@ -1205,10 +1207,11 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) | |||
1205 | { | 1207 | { |
1206 | struct drbd_socket *sock = &mdev->tconn->data; | 1208 | struct drbd_socket *sock = &mdev->tconn->data; |
1207 | unsigned int header_size = drbd_header_size(mdev->tconn); | 1209 | unsigned int header_size = drbd_header_size(mdev->tconn); |
1208 | struct p_compressed_bm *p = sock->sbuf; | 1210 | struct p_compressed_bm *p = sock->sbuf + header_size; |
1209 | int len, err; | 1211 | int len, err; |
1210 | 1212 | ||
1211 | len = fill_bitmap_rle_bits(mdev, p, DRBD_SOCKET_BUFFER_SIZE - sizeof(*p) /* FIXME */, c); | 1213 | len = fill_bitmap_rle_bits(mdev, p, |
1214 | DRBD_SOCKET_BUFFER_SIZE - header_size - sizeof(*p), c); | ||
1212 | if (len < 0) | 1215 | if (len < 0) |
1213 | return -EIO; | 1216 | return -EIO; |
1214 | 1217 | ||
@@ -1218,7 +1221,7 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) | |||
1218 | P_COMPRESSED_BITMAP, sizeof(*p) + len, | 1221 | P_COMPRESSED_BITMAP, sizeof(*p) + len, |
1219 | NULL, 0); | 1222 | NULL, 0); |
1220 | c->packets[0]++; | 1223 | c->packets[0]++; |
1221 | c->bytes[0] += sizeof(*p) + len; | 1224 | c->bytes[0] += header_size + sizeof(*p) + len; |
1222 | 1225 | ||
1223 | if (c->bit_offset >= c->bm_bits) | 1226 | if (c->bit_offset >= c->bm_bits) |
1224 | len = 0; /* DONE */ | 1227 | len = 0; /* DONE */ |
@@ -1227,17 +1230,15 @@ send_bitmap_rle_or_plain(struct drbd_conf *mdev, struct bm_xfer_ctx *c) | |||
1227 | * send a buffer full of plain text bits instead. */ | 1230 | * send a buffer full of plain text bits instead. */ |
1228 | unsigned int data_size; | 1231 | unsigned int data_size; |
1229 | unsigned long num_words; | 1232 | unsigned long num_words; |
1230 | struct p_header *h = sock->sbuf; | 1233 | unsigned long *p = sock->sbuf + header_size; |
1231 | 1234 | ||
1232 | data_size = DRBD_SOCKET_BUFFER_SIZE - header_size; | 1235 | data_size = DRBD_SOCKET_BUFFER_SIZE - header_size; |
1233 | num_words = min_t(size_t, data_size / sizeof(unsigned long), | 1236 | num_words = min_t(size_t, data_size / sizeof(*p), |
1234 | c->bm_words - c->word_offset); | 1237 | c->bm_words - c->word_offset); |
1235 | len = num_words * sizeof(unsigned long); | 1238 | len = num_words * sizeof(*p); |
1236 | if (len) | 1239 | if (len) |
1237 | drbd_bm_get_lel(mdev, c->word_offset, num_words, | 1240 | drbd_bm_get_lel(mdev, c->word_offset, num_words, p); |
1238 | (unsigned long *)h->payload); | 1241 | err = __send_command(mdev->tconn, mdev->vnr, sock, P_BITMAP, len, NULL, 0); |
1239 | err = __send_command(mdev->tconn, mdev->vnr, sock, P_BITMAP, | ||
1240 | sizeof(*h) + len, NULL, 0); | ||
1241 | c->word_offset += num_words; | 1242 | c->word_offset += num_words; |
1242 | c->bit_offset = c->word_offset * BITS_PER_LONG; | 1243 | c->bit_offset = c->word_offset * BITS_PER_LONG; |
1243 | 1244 | ||
@@ -2556,8 +2557,6 @@ int __init drbd_init(void) | |||
2556 | { | 2557 | { |
2557 | int err; | 2558 | int err; |
2558 | 2559 | ||
2559 | BUILD_BUG_ON(sizeof(struct p_connection_features) != 80); | ||
2560 | |||
2561 | if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) { | 2560 | if (minor_count < DRBD_MINOR_COUNT_MIN || minor_count > DRBD_MINOR_COUNT_MAX) { |
2562 | printk(KERN_ERR | 2561 | printk(KERN_ERR |
2563 | "drbd: invalid minor_count (%d)\n", minor_count); | 2562 | "drbd: invalid minor_count (%d)\n", minor_count); |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 74ed3ac263f3..7e0ab2246fb6 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -52,6 +52,7 @@ struct packet_info { | |||
52 | enum drbd_packet cmd; | 52 | enum drbd_packet cmd; |
53 | unsigned int size; | 53 | unsigned int size; |
54 | unsigned int vnr; | 54 | unsigned int vnr; |
55 | void *data; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | enum finish_epoch { | 58 | enum finish_epoch { |
@@ -729,14 +730,14 @@ out: | |||
729 | return s_estab; | 730 | return s_estab; |
730 | } | 731 | } |
731 | 732 | ||
732 | static int decode_header(struct drbd_tconn *, struct p_header *, struct packet_info *); | 733 | static int decode_header(struct drbd_tconn *, void *, struct packet_info *); |
733 | 734 | ||
734 | static int send_first_packet(struct drbd_tconn *tconn, struct drbd_socket *sock, | 735 | static int send_first_packet(struct drbd_tconn *tconn, struct drbd_socket *sock, |
735 | enum drbd_packet cmd) | 736 | enum drbd_packet cmd) |
736 | { | 737 | { |
737 | if (!conn_prepare_command(tconn, sock)) | 738 | if (!conn_prepare_command(tconn, sock)) |
738 | return -EIO; | 739 | return -EIO; |
739 | return conn_send_command(tconn, sock, cmd, sizeof(struct p_header), NULL, 0); | 740 | return conn_send_command(tconn, sock, cmd, 0, NULL, 0); |
740 | } | 741 | } |
741 | 742 | ||
742 | static int receive_first_packet(struct drbd_tconn *tconn, struct socket *sock) | 743 | static int receive_first_packet(struct drbd_tconn *tconn, struct socket *sock) |
@@ -978,36 +979,43 @@ out_release_sockets: | |||
978 | return -1; | 979 | return -1; |
979 | } | 980 | } |
980 | 981 | ||
981 | static int decode_header(struct drbd_tconn *tconn, struct p_header *h, struct packet_info *pi) | 982 | static int decode_header(struct drbd_tconn *tconn, void *header, struct packet_info *pi) |
982 | { | 983 | { |
983 | if (h->h80.magic == cpu_to_be32(DRBD_MAGIC)) { | 984 | unsigned int header_size = drbd_header_size(tconn); |
984 | pi->cmd = be16_to_cpu(h->h80.command); | 985 | |
985 | pi->size = be16_to_cpu(h->h80.length); | 986 | if (header_size == sizeof(struct p_header95) && |
986 | pi->vnr = 0; | 987 | *(__be16 *)header == cpu_to_be16(DRBD_MAGIC_BIG)) { |
987 | } else if (h->h95.magic == cpu_to_be16(DRBD_MAGIC_BIG)) { | 988 | struct p_header95 *h = header; |
988 | pi->cmd = be16_to_cpu(h->h95.command); | 989 | |
989 | pi->size = be32_to_cpu(h->h95.length) & 0x00ffffff; | 990 | pi->cmd = be16_to_cpu(h->command); |
991 | pi->size = be32_to_cpu(h->length) & 0x00ffffff; | ||
992 | pi->vnr = 0; | ||
993 | } else if (header_size == sizeof(struct p_header80) && | ||
994 | *(__be32 *)header == cpu_to_be32(DRBD_MAGIC)) { | ||
995 | struct p_header80 *h = header; | ||
996 | pi->cmd = be16_to_cpu(h->command); | ||
997 | pi->size = be16_to_cpu(h->length); | ||
990 | pi->vnr = 0; | 998 | pi->vnr = 0; |
991 | } else { | 999 | } else { |
992 | conn_err(tconn, "magic?? on data m: 0x%08x c: %d l: %d\n", | 1000 | conn_err(tconn, "Wrong magic value 0x%08x in protocol version %d\n", |
993 | be32_to_cpu(h->h80.magic), | 1001 | be32_to_cpu(*(__be32 *)header), |
994 | be16_to_cpu(h->h80.command), | 1002 | tconn->agreed_pro_version); |
995 | be16_to_cpu(h->h80.length)); | ||
996 | return -EINVAL; | 1003 | return -EINVAL; |
997 | } | 1004 | } |
1005 | pi->data = header + header_size; | ||
998 | return 0; | 1006 | return 0; |
999 | } | 1007 | } |
1000 | 1008 | ||
1001 | static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi) | 1009 | static int drbd_recv_header(struct drbd_tconn *tconn, struct packet_info *pi) |
1002 | { | 1010 | { |
1003 | struct p_header *h = tconn->data.rbuf; | 1011 | void *buffer = tconn->data.rbuf; |
1004 | int err; | 1012 | int err; |
1005 | 1013 | ||
1006 | err = drbd_recv_all_warn(tconn, h, drbd_header_size(tconn)); | 1014 | err = drbd_recv_all_warn(tconn, buffer, drbd_header_size(tconn)); |
1007 | if (err) | 1015 | if (err) |
1008 | return err; | 1016 | return err; |
1009 | 1017 | ||
1010 | err = decode_header(tconn, h, pi); | 1018 | err = decode_header(tconn, buffer, pi); |
1011 | tconn->last_received = jiffies; | 1019 | tconn->last_received = jiffies; |
1012 | 1020 | ||
1013 | return err; | 1021 | return err; |
@@ -1242,7 +1250,7 @@ static int receive_Barrier(struct drbd_tconn *tconn, struct packet_info *pi) | |||
1242 | { | 1250 | { |
1243 | struct drbd_conf *mdev; | 1251 | struct drbd_conf *mdev; |
1244 | int rv; | 1252 | int rv; |
1245 | struct p_barrier *p = tconn->data.rbuf; | 1253 | struct p_barrier *p = pi->data; |
1246 | struct drbd_epoch *epoch; | 1254 | struct drbd_epoch *epoch; |
1247 | 1255 | ||
1248 | mdev = vnr_to_mdev(tconn, pi->vnr); | 1256 | mdev = vnr_to_mdev(tconn, pi->vnr); |
@@ -1560,7 +1568,7 @@ static int receive_DataReply(struct drbd_tconn *tconn, struct packet_info *pi) | |||
1560 | struct drbd_request *req; | 1568 | struct drbd_request *req; |
1561 | sector_t sector; | 1569 | sector_t sector; |
1562 | int err; | 1570 | int err; |
1563 | struct p_data *p = tconn->data.rbuf; | 1571 | struct p_data *p = pi->data; |
1564 | 1572 | ||
1565 | mdev = vnr_to_mdev(tconn, pi->vnr); | 1573 | mdev = vnr_to_mdev(tconn, pi->vnr); |
1566 | if (!mdev) | 1574 | if (!mdev) |
@@ -1592,7 +1600,7 @@ static int receive_RSDataReply(struct drbd_tconn *tconn, struct packet_info *pi) | |||
1592 | struct drbd_conf *mdev; | 1600 | struct drbd_conf *mdev; |
1593 | sector_t sector; | 1601 | sector_t sector; |
1594 | int err; | 1602 | int err; |
1595 | struct p_data *p = tconn->data.rbuf; | 1603 | struct p_data *p = pi->data; |
1596 | 1604 | ||
1597 | mdev = vnr_to_mdev(tconn, pi->vnr); | 1605 | mdev = vnr_to_mdev(tconn, pi->vnr); |
1598 | if (!mdev) | 1606 | if (!mdev) |
@@ -1985,7 +1993,7 @@ static int receive_Data(struct drbd_tconn *tconn, struct packet_info *pi) | |||
1985 | struct drbd_conf *mdev; | 1993 | struct drbd_conf *mdev; |
1986 | sector_t sector; | 1994 | sector_t sector; |
1987 | struct drbd_peer_request *peer_req; | 1995 | struct drbd_peer_request *peer_req; |
1988 | struct p_data *p = tconn->data.rbuf; | 1996 | struct p_data *p = pi->data; |
1989 | u32 peer_seq = be32_to_cpu(p->seq_num); | 1997 | u32 peer_seq = be32_to_cpu(p->seq_num); |
1990 | int rw = WRITE; | 1998 | int rw = WRITE; |
1991 | u32 dp_flags; | 1999 | u32 dp_flags; |
@@ -2173,7 +2181,7 @@ static int receive_DataRequest(struct drbd_tconn *tconn, struct packet_info *pi) | |||
2173 | struct digest_info *di = NULL; | 2181 | struct digest_info *di = NULL; |
2174 | int size, verb; | 2182 | int size, verb; |
2175 | unsigned int fault_type; | 2183 | unsigned int fault_type; |
2176 | struct p_block_req *p = tconn->data.rbuf; | 2184 | struct p_block_req *p = pi->data; |
2177 | 2185 | ||
2178 | mdev = vnr_to_mdev(tconn, pi->vnr); | 2186 | mdev = vnr_to_mdev(tconn, pi->vnr); |
2179 | if (!mdev) | 2187 | if (!mdev) |
@@ -2893,7 +2901,7 @@ static int cmp_after_sb(enum drbd_after_sb_p peer, enum drbd_after_sb_p self) | |||
2893 | 2901 | ||
2894 | static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi) | 2902 | static int receive_protocol(struct drbd_tconn *tconn, struct packet_info *pi) |
2895 | { | 2903 | { |
2896 | struct p_protocol *p = tconn->data.rbuf; | 2904 | struct p_protocol *p = pi->data; |
2897 | int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; | 2905 | int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; |
2898 | int p_want_lose, p_two_primaries, cf; | 2906 | int p_want_lose, p_two_primaries, cf; |
2899 | char p_integrity_alg[SHARED_SECRET_MAX] = ""; | 2907 | char p_integrity_alg[SHARED_SECRET_MAX] = ""; |
@@ -3033,7 +3041,7 @@ static int config_unknown_volume(struct drbd_tconn *tconn, struct packet_info *p | |||
3033 | static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi) | 3041 | static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi) |
3034 | { | 3042 | { |
3035 | struct drbd_conf *mdev; | 3043 | struct drbd_conf *mdev; |
3036 | struct p_rs_param_95 *p = tconn->data.rbuf; | 3044 | struct p_rs_param_95 *p; |
3037 | unsigned int header_size, data_size, exp_max_sz; | 3045 | unsigned int header_size, data_size, exp_max_sz; |
3038 | struct crypto_hash *verify_tfm = NULL; | 3046 | struct crypto_hash *verify_tfm = NULL; |
3039 | struct crypto_hash *csums_tfm = NULL; | 3047 | struct crypto_hash *csums_tfm = NULL; |
@@ -3059,22 +3067,23 @@ static int receive_SyncParam(struct drbd_tconn *tconn, struct packet_info *pi) | |||
3059 | } | 3067 | } |
3060 | 3068 | ||
3061 | if (apv <= 88) { | 3069 | if (apv <= 88) { |
3062 | header_size = sizeof(struct p_rs_param) - sizeof(struct p_header); | 3070 | header_size = sizeof(struct p_rs_param); |
3063 | data_size = pi->size - header_size; | 3071 | data_size = pi->size - header_size; |
3064 | } else if (apv <= 94) { | 3072 | } else if (apv <= 94) { |
3065 | header_size = sizeof(struct p_rs_param_89) - sizeof(struct p_header); | 3073 | header_size = sizeof(struct p_rs_param_89); |
3066 | data_size = pi->size - header_size; | 3074 | data_size = pi->size - header_size; |
3067 | D_ASSERT(data_size == 0); | 3075 | D_ASSERT(data_size == 0); |
3068 | } else { | 3076 | } else { |
3069 | header_size = sizeof(struct p_rs_param_95) - sizeof(struct p_header); | 3077 | header_size = sizeof(struct p_rs_param_95); |
3070 | data_size = pi->size - header_size; | 3078 | data_size = pi->size - header_size; |
3071 | D_ASSERT(data_size == 0); | 3079 | D_ASSERT(data_size == 0); |
3072 | } | 3080 | } |
3073 | 3081 | ||
3074 | /* initialize verify_alg and csums_alg */ | 3082 | /* initialize verify_alg and csums_alg */ |
3083 | p = pi->data; | ||
3075 | memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); | 3084 | memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); |
3076 | 3085 | ||
3077 | err = drbd_recv_all(mdev->tconn, &p->head.payload, header_size); | 3086 | err = drbd_recv_all(mdev->tconn, p, header_size); |
3078 | if (err) | 3087 | if (err) |
3079 | return err; | 3088 | return err; |
3080 | 3089 | ||
@@ -3209,7 +3218,7 @@ static void warn_if_differ_considerably(struct drbd_conf *mdev, | |||
3209 | static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi) | 3218 | static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi) |
3210 | { | 3219 | { |
3211 | struct drbd_conf *mdev; | 3220 | struct drbd_conf *mdev; |
3212 | struct p_sizes *p = tconn->data.rbuf; | 3221 | struct p_sizes *p = pi->data; |
3213 | enum determine_dev_size dd = unchanged; | 3222 | enum determine_dev_size dd = unchanged; |
3214 | sector_t p_size, p_usize, my_usize; | 3223 | sector_t p_size, p_usize, my_usize; |
3215 | int ldsc = 0; /* local disk size changed */ | 3224 | int ldsc = 0; /* local disk size changed */ |
@@ -3311,7 +3320,7 @@ static int receive_sizes(struct drbd_tconn *tconn, struct packet_info *pi) | |||
3311 | static int receive_uuids(struct drbd_tconn *tconn, struct packet_info *pi) | 3320 | static int receive_uuids(struct drbd_tconn *tconn, struct packet_info *pi) |
3312 | { | 3321 | { |
3313 | struct drbd_conf *mdev; | 3322 | struct drbd_conf *mdev; |
3314 | struct p_uuids *p = tconn->data.rbuf; | 3323 | struct p_uuids *p = pi->data; |
3315 | u64 *p_uuid; | 3324 | u64 *p_uuid; |
3316 | int i, updated_uuids = 0; | 3325 | int i, updated_uuids = 0; |
3317 | 3326 | ||
@@ -3411,7 +3420,7 @@ static union drbd_state convert_state(union drbd_state ps) | |||
3411 | static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi) | 3420 | static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi) |
3412 | { | 3421 | { |
3413 | struct drbd_conf *mdev; | 3422 | struct drbd_conf *mdev; |
3414 | struct p_req_state *p = tconn->data.rbuf; | 3423 | struct p_req_state *p = pi->data; |
3415 | union drbd_state mask, val; | 3424 | union drbd_state mask, val; |
3416 | enum drbd_state_rv rv; | 3425 | enum drbd_state_rv rv; |
3417 | 3426 | ||
@@ -3441,7 +3450,7 @@ static int receive_req_state(struct drbd_tconn *tconn, struct packet_info *pi) | |||
3441 | 3450 | ||
3442 | static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *pi) | 3451 | static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info *pi) |
3443 | { | 3452 | { |
3444 | struct p_req_state *p = tconn->data.rbuf; | 3453 | struct p_req_state *p = pi->data; |
3445 | union drbd_state mask, val; | 3454 | union drbd_state mask, val; |
3446 | enum drbd_state_rv rv; | 3455 | enum drbd_state_rv rv; |
3447 | 3456 | ||
@@ -3466,7 +3475,7 @@ static int receive_req_conn_state(struct drbd_tconn *tconn, struct packet_info * | |||
3466 | static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi) | 3475 | static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi) |
3467 | { | 3476 | { |
3468 | struct drbd_conf *mdev; | 3477 | struct drbd_conf *mdev; |
3469 | struct p_state *p = tconn->data.rbuf; | 3478 | struct p_state *p = pi->data; |
3470 | union drbd_state os, ns, peer_state; | 3479 | union drbd_state os, ns, peer_state; |
3471 | enum drbd_disk_state real_peer_disk; | 3480 | enum drbd_disk_state real_peer_disk; |
3472 | enum chg_state_flags cs_flags; | 3481 | enum chg_state_flags cs_flags; |
@@ -3623,7 +3632,7 @@ static int receive_state(struct drbd_tconn *tconn, struct packet_info *pi) | |||
3623 | static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi) | 3632 | static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi) |
3624 | { | 3633 | { |
3625 | struct drbd_conf *mdev; | 3634 | struct drbd_conf *mdev; |
3626 | struct p_rs_uuid *p = tconn->data.rbuf; | 3635 | struct p_rs_uuid *p = pi->data; |
3627 | 3636 | ||
3628 | mdev = vnr_to_mdev(tconn, pi->vnr); | 3637 | mdev = vnr_to_mdev(tconn, pi->vnr); |
3629 | if (!mdev) | 3638 | if (!mdev) |
@@ -3661,14 +3670,13 @@ static int receive_sync_uuid(struct drbd_tconn *tconn, struct packet_info *pi) | |||
3661 | */ | 3670 | */ |
3662 | static int | 3671 | static int |
3663 | receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size, | 3672 | receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size, |
3664 | struct p_header *h, struct bm_xfer_ctx *c) | 3673 | unsigned long *p, struct bm_xfer_ctx *c) |
3665 | { | 3674 | { |
3666 | unsigned long *buffer = (unsigned long *)h->payload; | ||
3667 | unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - | 3675 | unsigned int data_size = DRBD_SOCKET_BUFFER_SIZE - |
3668 | drbd_header_size(mdev->tconn); | 3676 | drbd_header_size(mdev->tconn); |
3669 | unsigned int num_words = min_t(size_t, data_size / sizeof(unsigned long), | 3677 | unsigned int num_words = min_t(size_t, data_size / sizeof(*p), |
3670 | c->bm_words - c->word_offset); | 3678 | c->bm_words - c->word_offset); |
3671 | unsigned int want = num_words * sizeof(unsigned long); | 3679 | unsigned int want = num_words * sizeof(*p); |
3672 | int err; | 3680 | int err; |
3673 | 3681 | ||
3674 | if (want != size) { | 3682 | if (want != size) { |
@@ -3677,11 +3685,11 @@ receive_bitmap_plain(struct drbd_conf *mdev, unsigned int size, | |||
3677 | } | 3685 | } |
3678 | if (want == 0) | 3686 | if (want == 0) |
3679 | return 0; | 3687 | return 0; |
3680 | err = drbd_recv_all(mdev->tconn, buffer, want); | 3688 | err = drbd_recv_all(mdev->tconn, p, want); |
3681 | if (err) | 3689 | if (err) |
3682 | return err; | 3690 | return err; |
3683 | 3691 | ||
3684 | drbd_bm_merge_lel(mdev, c->word_offset, num_words, buffer); | 3692 | drbd_bm_merge_lel(mdev, c->word_offset, num_words, p); |
3685 | 3693 | ||
3686 | c->word_offset += num_words; | 3694 | c->word_offset += num_words; |
3687 | c->bit_offset = c->word_offset * BITS_PER_LONG; | 3695 | c->bit_offset = c->word_offset * BITS_PER_LONG; |
@@ -3784,7 +3792,7 @@ decode_bitmap_c(struct drbd_conf *mdev, | |||
3784 | unsigned int len) | 3792 | unsigned int len) |
3785 | { | 3793 | { |
3786 | if (dcbp_get_code(p) == RLE_VLI_Bits) | 3794 | if (dcbp_get_code(p) == RLE_VLI_Bits) |
3787 | return recv_bm_rle_bits(mdev, p, c, len); | 3795 | return recv_bm_rle_bits(mdev, p, c, len - sizeof(*p)); |
3788 | 3796 | ||
3789 | /* other variants had been implemented for evaluation, | 3797 | /* other variants had been implemented for evaluation, |
3790 | * but have been dropped as this one turned out to be "best" | 3798 | * but have been dropped as this one turned out to be "best" |
@@ -3844,7 +3852,6 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi) | |||
3844 | struct drbd_conf *mdev; | 3852 | struct drbd_conf *mdev; |
3845 | struct bm_xfer_ctx c; | 3853 | struct bm_xfer_ctx c; |
3846 | int err; | 3854 | int err; |
3847 | struct p_header *h = tconn->data.rbuf; | ||
3848 | 3855 | ||
3849 | mdev = vnr_to_mdev(tconn, pi->vnr); | 3856 | mdev = vnr_to_mdev(tconn, pi->vnr); |
3850 | if (!mdev) | 3857 | if (!mdev) |
@@ -3860,28 +3867,26 @@ static int receive_bitmap(struct drbd_tconn *tconn, struct packet_info *pi) | |||
3860 | }; | 3867 | }; |
3861 | 3868 | ||
3862 | for(;;) { | 3869 | for(;;) { |
3863 | if (pi->cmd == P_BITMAP) { | 3870 | if (pi->cmd == P_BITMAP) |
3864 | err = receive_bitmap_plain(mdev, pi->size, h, &c); | 3871 | err = receive_bitmap_plain(mdev, pi->size, pi->data, &c); |
3865 | } else if (pi->cmd == P_COMPRESSED_BITMAP) { | 3872 | else if (pi->cmd == P_COMPRESSED_BITMAP) { |
3866 | /* MAYBE: sanity check that we speak proto >= 90, | 3873 | /* MAYBE: sanity check that we speak proto >= 90, |
3867 | * and the feature is enabled! */ | 3874 | * and the feature is enabled! */ |
3868 | struct p_compressed_bm *p; | 3875 | struct p_compressed_bm *p = pi->data; |
3869 | 3876 | ||
3870 | if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(tconn)) { | 3877 | if (pi->size > DRBD_SOCKET_BUFFER_SIZE - drbd_header_size(tconn)) { |
3871 | dev_err(DEV, "ReportCBitmap packet too large\n"); | 3878 | dev_err(DEV, "ReportCBitmap packet too large\n"); |
3872 | err = -EIO; | 3879 | err = -EIO; |
3873 | goto out; | 3880 | goto out; |
3874 | } | 3881 | } |
3875 | 3882 | if (pi->size <= sizeof(*p)) { | |
3876 | p = mdev->tconn->data.rbuf; | ||
3877 | err = drbd_recv_all(mdev->tconn, p->head.payload, pi->size); | ||
3878 | if (err) | ||
3879 | goto out; | ||
3880 | if (pi->size <= (sizeof(*p) - sizeof(p->head))) { | ||
3881 | dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", pi->size); | 3883 | dev_err(DEV, "ReportCBitmap packet too small (l:%u)\n", pi->size); |
3882 | err = -EIO; | 3884 | err = -EIO; |
3883 | goto out; | 3885 | goto out; |
3884 | } | 3886 | } |
3887 | err = drbd_recv_all(mdev->tconn, p, pi->size); | ||
3888 | if (err) | ||
3889 | goto out; | ||
3885 | err = decode_bitmap_c(mdev, p, &c, pi->size); | 3890 | err = decode_bitmap_c(mdev, p, &c, pi->size); |
3886 | } else { | 3891 | } else { |
3887 | dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd); | 3892 | dev_warn(DEV, "receive_bitmap: cmd neither ReportBitMap nor ReportCBitMap (is 0x%x)", pi->cmd); |
@@ -3948,7 +3953,7 @@ static int receive_UnplugRemote(struct drbd_tconn *tconn, struct packet_info *pi | |||
3948 | static int receive_out_of_sync(struct drbd_tconn *tconn, struct packet_info *pi) | 3953 | static int receive_out_of_sync(struct drbd_tconn *tconn, struct packet_info *pi) |
3949 | { | 3954 | { |
3950 | struct drbd_conf *mdev; | 3955 | struct drbd_conf *mdev; |
3951 | struct p_block_desc *p = tconn->data.rbuf; | 3956 | struct p_block_desc *p = pi->data; |
3952 | 3957 | ||
3953 | mdev = vnr_to_mdev(tconn, pi->vnr); | 3958 | mdev = vnr_to_mdev(tconn, pi->vnr); |
3954 | if (!mdev) | 3959 | if (!mdev) |
@@ -3980,13 +3985,13 @@ static struct data_cmd drbd_cmd_handler[] = { | |||
3980 | [P_DATA_REPLY] = { 1, sizeof(struct p_data), receive_DataReply }, | 3985 | [P_DATA_REPLY] = { 1, sizeof(struct p_data), receive_DataReply }, |
3981 | [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), receive_RSDataReply } , | 3986 | [P_RS_DATA_REPLY] = { 1, sizeof(struct p_data), receive_RSDataReply } , |
3982 | [P_BARRIER] = { 0, sizeof(struct p_barrier), receive_Barrier } , | 3987 | [P_BARRIER] = { 0, sizeof(struct p_barrier), receive_Barrier } , |
3983 | [P_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } , | 3988 | [P_BITMAP] = { 1, 0, receive_bitmap } , |
3984 | [P_COMPRESSED_BITMAP] = { 1, sizeof(struct p_header), receive_bitmap } , | 3989 | [P_COMPRESSED_BITMAP] = { 1, 0, receive_bitmap } , |
3985 | [P_UNPLUG_REMOTE] = { 0, sizeof(struct p_header), receive_UnplugRemote }, | 3990 | [P_UNPLUG_REMOTE] = { 0, 0, receive_UnplugRemote }, |
3986 | [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, | 3991 | [P_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, |
3987 | [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, | 3992 | [P_RS_DATA_REQUEST] = { 0, sizeof(struct p_block_req), receive_DataRequest }, |
3988 | [P_SYNC_PARAM] = { 1, sizeof(struct p_header), receive_SyncParam }, | 3993 | [P_SYNC_PARAM] = { 1, 0, receive_SyncParam }, |
3989 | [P_SYNC_PARAM89] = { 1, sizeof(struct p_header), receive_SyncParam }, | 3994 | [P_SYNC_PARAM89] = { 1, 0, receive_SyncParam }, |
3990 | [P_PROTOCOL] = { 1, sizeof(struct p_protocol), receive_protocol }, | 3995 | [P_PROTOCOL] = { 1, sizeof(struct p_protocol), receive_protocol }, |
3991 | [P_UUIDS] = { 0, sizeof(struct p_uuids), receive_uuids }, | 3996 | [P_UUIDS] = { 0, sizeof(struct p_uuids), receive_uuids }, |
3992 | [P_SIZES] = { 0, sizeof(struct p_sizes), receive_sizes }, | 3997 | [P_SIZES] = { 0, sizeof(struct p_sizes), receive_sizes }, |
@@ -4003,7 +4008,6 @@ static struct data_cmd drbd_cmd_handler[] = { | |||
4003 | 4008 | ||
4004 | static void drbdd(struct drbd_tconn *tconn) | 4009 | static void drbdd(struct drbd_tconn *tconn) |
4005 | { | 4010 | { |
4006 | struct p_header *header = tconn->data.rbuf; | ||
4007 | struct packet_info pi; | 4011 | struct packet_info pi; |
4008 | size_t shs; /* sub header size */ | 4012 | size_t shs; /* sub header size */ |
4009 | int err; | 4013 | int err; |
@@ -4021,14 +4025,14 @@ static void drbdd(struct drbd_tconn *tconn) | |||
4021 | goto err_out; | 4025 | goto err_out; |
4022 | } | 4026 | } |
4023 | 4027 | ||
4024 | shs = cmd->pkt_size - sizeof(struct p_header); | 4028 | shs = cmd->pkt_size; |
4025 | if (pi.size - shs > 0 && !cmd->expect_payload) { | 4029 | if (pi.size > shs && !cmd->expect_payload) { |
4026 | conn_err(tconn, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size); | 4030 | conn_err(tconn, "No payload expected %s l:%d\n", cmdname(pi.cmd), pi.size); |
4027 | goto err_out; | 4031 | goto err_out; |
4028 | } | 4032 | } |
4029 | 4033 | ||
4030 | if (shs) { | 4034 | if (shs) { |
4031 | err = drbd_recv_all_warn(tconn, &header->payload, shs); | 4035 | err = drbd_recv_all_warn(tconn, pi.data, shs); |
4032 | if (err) | 4036 | if (err) |
4033 | goto err_out; | 4037 | goto err_out; |
4034 | pi.size -= shs; | 4038 | pi.size -= shs; |
@@ -4219,8 +4223,8 @@ static int drbd_send_features(struct drbd_tconn *tconn) | |||
4219 | static int drbd_do_features(struct drbd_tconn *tconn) | 4223 | static int drbd_do_features(struct drbd_tconn *tconn) |
4220 | { | 4224 | { |
4221 | /* ASSERT current == tconn->receiver ... */ | 4225 | /* ASSERT current == tconn->receiver ... */ |
4222 | struct p_connection_features *p = tconn->data.rbuf; | 4226 | struct p_connection_features *p; |
4223 | const int expect = sizeof(struct p_connection_features) - sizeof(struct p_header80); | 4227 | const int expect = sizeof(struct p_connection_features); |
4224 | struct packet_info pi; | 4228 | struct packet_info pi; |
4225 | int err; | 4229 | int err; |
4226 | 4230 | ||
@@ -4244,7 +4248,8 @@ static int drbd_do_features(struct drbd_tconn *tconn) | |||
4244 | return -1; | 4248 | return -1; |
4245 | } | 4249 | } |
4246 | 4250 | ||
4247 | err = drbd_recv_all_warn(tconn, &p->head.payload, expect); | 4251 | p = pi.data; |
4252 | err = drbd_recv_all_warn(tconn, p, expect); | ||
4248 | if (err) | 4253 | if (err) |
4249 | return 0; | 4254 | return 0; |
4250 | 4255 | ||
@@ -4322,8 +4327,7 @@ static int drbd_do_auth(struct drbd_tconn *tconn) | |||
4322 | rv = 0; | 4327 | rv = 0; |
4323 | goto fail; | 4328 | goto fail; |
4324 | } | 4329 | } |
4325 | rv = !conn_send_command(tconn, sock, P_AUTH_CHALLENGE, | 4330 | rv = !conn_send_command(tconn, sock, P_AUTH_CHALLENGE, 0, |
4326 | sizeof(struct p_header), | ||
4327 | my_challenge, CHALLENGE_LEN); | 4331 | my_challenge, CHALLENGE_LEN); |
4328 | if (!rv) | 4332 | if (!rv) |
4329 | goto fail; | 4333 | goto fail; |
@@ -4382,8 +4386,7 @@ static int drbd_do_auth(struct drbd_tconn *tconn) | |||
4382 | rv = 0; | 4386 | rv = 0; |
4383 | goto fail; | 4387 | goto fail; |
4384 | } | 4388 | } |
4385 | rv = !conn_send_command(tconn, sock, P_AUTH_RESPONSE, | 4389 | rv = !conn_send_command(tconn, sock, P_AUTH_RESPONSE, 0, |
4386 | sizeof(struct p_header), | ||
4387 | response, resp_size); | 4390 | response, resp_size); |
4388 | if (!rv) | 4391 | if (!rv) |
4389 | goto fail; | 4392 | goto fail; |
@@ -4482,7 +4485,7 @@ int drbdd_init(struct drbd_thread *thi) | |||
4482 | 4485 | ||
4483 | static int got_conn_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi) | 4486 | static int got_conn_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi) |
4484 | { | 4487 | { |
4485 | struct p_req_state_reply *p = tconn->meta.rbuf; | 4488 | struct p_req_state_reply *p = pi->data; |
4486 | int retcode = be32_to_cpu(p->retcode); | 4489 | int retcode = be32_to_cpu(p->retcode); |
4487 | 4490 | ||
4488 | if (retcode >= SS_SUCCESS) { | 4491 | if (retcode >= SS_SUCCESS) { |
@@ -4500,7 +4503,7 @@ static int got_conn_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4500 | static int got_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi) | 4503 | static int got_RqSReply(struct drbd_tconn *tconn, struct packet_info *pi) |
4501 | { | 4504 | { |
4502 | struct drbd_conf *mdev; | 4505 | struct drbd_conf *mdev; |
4503 | struct p_req_state_reply *p = tconn->meta.rbuf; | 4506 | struct p_req_state_reply *p = pi->data; |
4504 | int retcode = be32_to_cpu(p->retcode); | 4507 | int retcode = be32_to_cpu(p->retcode); |
4505 | 4508 | ||
4506 | mdev = vnr_to_mdev(tconn, pi->vnr); | 4509 | mdev = vnr_to_mdev(tconn, pi->vnr); |
@@ -4538,7 +4541,7 @@ static int got_PingAck(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4538 | static int got_IsInSync(struct drbd_tconn *tconn, struct packet_info *pi) | 4541 | static int got_IsInSync(struct drbd_tconn *tconn, struct packet_info *pi) |
4539 | { | 4542 | { |
4540 | struct drbd_conf *mdev; | 4543 | struct drbd_conf *mdev; |
4541 | struct p_block_ack *p = tconn->meta.rbuf; | 4544 | struct p_block_ack *p = pi->data; |
4542 | sector_t sector = be64_to_cpu(p->sector); | 4545 | sector_t sector = be64_to_cpu(p->sector); |
4543 | int blksize = be32_to_cpu(p->blksize); | 4546 | int blksize = be32_to_cpu(p->blksize); |
4544 | 4547 | ||
@@ -4588,7 +4591,7 @@ validate_req_change_req_state(struct drbd_conf *mdev, u64 id, sector_t sector, | |||
4588 | static int got_BlockAck(struct drbd_tconn *tconn, struct packet_info *pi) | 4591 | static int got_BlockAck(struct drbd_tconn *tconn, struct packet_info *pi) |
4589 | { | 4592 | { |
4590 | struct drbd_conf *mdev; | 4593 | struct drbd_conf *mdev; |
4591 | struct p_block_ack *p = tconn->meta.rbuf; | 4594 | struct p_block_ack *p = pi->data; |
4592 | sector_t sector = be64_to_cpu(p->sector); | 4595 | sector_t sector = be64_to_cpu(p->sector); |
4593 | int blksize = be32_to_cpu(p->blksize); | 4596 | int blksize = be32_to_cpu(p->blksize); |
4594 | enum drbd_req_event what; | 4597 | enum drbd_req_event what; |
@@ -4638,7 +4641,7 @@ static int got_BlockAck(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4638 | static int got_NegAck(struct drbd_tconn *tconn, struct packet_info *pi) | 4641 | static int got_NegAck(struct drbd_tconn *tconn, struct packet_info *pi) |
4639 | { | 4642 | { |
4640 | struct drbd_conf *mdev; | 4643 | struct drbd_conf *mdev; |
4641 | struct p_block_ack *p = tconn->meta.rbuf; | 4644 | struct p_block_ack *p = pi->data; |
4642 | sector_t sector = be64_to_cpu(p->sector); | 4645 | sector_t sector = be64_to_cpu(p->sector); |
4643 | int size = be32_to_cpu(p->blksize); | 4646 | int size = be32_to_cpu(p->blksize); |
4644 | bool missing_ok = tconn->net_conf->wire_protocol == DRBD_PROT_A || | 4647 | bool missing_ok = tconn->net_conf->wire_protocol == DRBD_PROT_A || |
@@ -4676,7 +4679,7 @@ static int got_NegAck(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4676 | static int got_NegDReply(struct drbd_tconn *tconn, struct packet_info *pi) | 4679 | static int got_NegDReply(struct drbd_tconn *tconn, struct packet_info *pi) |
4677 | { | 4680 | { |
4678 | struct drbd_conf *mdev; | 4681 | struct drbd_conf *mdev; |
4679 | struct p_block_ack *p = tconn->meta.rbuf; | 4682 | struct p_block_ack *p = pi->data; |
4680 | sector_t sector = be64_to_cpu(p->sector); | 4683 | sector_t sector = be64_to_cpu(p->sector); |
4681 | 4684 | ||
4682 | mdev = vnr_to_mdev(tconn, pi->vnr); | 4685 | mdev = vnr_to_mdev(tconn, pi->vnr); |
@@ -4698,7 +4701,7 @@ static int got_NegRSDReply(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4698 | struct drbd_conf *mdev; | 4701 | struct drbd_conf *mdev; |
4699 | sector_t sector; | 4702 | sector_t sector; |
4700 | int size; | 4703 | int size; |
4701 | struct p_block_ack *p = tconn->meta.rbuf; | 4704 | struct p_block_ack *p = pi->data; |
4702 | 4705 | ||
4703 | mdev = vnr_to_mdev(tconn, pi->vnr); | 4706 | mdev = vnr_to_mdev(tconn, pi->vnr); |
4704 | if (!mdev) | 4707 | if (!mdev) |
@@ -4732,7 +4735,7 @@ static int got_NegRSDReply(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4732 | static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi) | 4735 | static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi) |
4733 | { | 4736 | { |
4734 | struct drbd_conf *mdev; | 4737 | struct drbd_conf *mdev; |
4735 | struct p_barrier_ack *p = tconn->meta.rbuf; | 4738 | struct p_barrier_ack *p = pi->data; |
4736 | 4739 | ||
4737 | mdev = vnr_to_mdev(tconn, pi->vnr); | 4740 | mdev = vnr_to_mdev(tconn, pi->vnr); |
4738 | if (!mdev) | 4741 | if (!mdev) |
@@ -4753,7 +4756,7 @@ static int got_BarrierAck(struct drbd_tconn *tconn, struct packet_info *pi) | |||
4753 | static int got_OVResult(struct drbd_tconn *tconn, struct packet_info *pi) | 4756 | static int got_OVResult(struct drbd_tconn *tconn, struct packet_info *pi) |
4754 | { | 4757 | { |
4755 | struct drbd_conf *mdev; | 4758 | struct drbd_conf *mdev; |
4756 | struct p_block_ack *p = tconn->meta.rbuf; | 4759 | struct p_block_ack *p = pi->data; |
4757 | struct drbd_work *w; | 4760 | struct drbd_work *w; |
4758 | sector_t sector; | 4761 | sector_t sector; |
4759 | int size; | 4762 | int size; |
@@ -4837,8 +4840,8 @@ struct asender_cmd { | |||
4837 | }; | 4840 | }; |
4838 | 4841 | ||
4839 | static struct asender_cmd asender_tbl[] = { | 4842 | static struct asender_cmd asender_tbl[] = { |
4840 | [P_PING] = { sizeof(struct p_header), got_Ping }, | 4843 | [P_PING] = { 0, got_Ping }, |
4841 | [P_PING_ACK] = { sizeof(struct p_header), got_PingAck }, | 4844 | [P_PING_ACK] = { 0, got_PingAck }, |
4842 | [P_RECV_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, | 4845 | [P_RECV_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, |
4843 | [P_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, | 4846 | [P_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, |
4844 | [P_RS_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, | 4847 | [P_RS_WRITE_ACK] = { sizeof(struct p_block_ack), got_BlockAck }, |
@@ -4859,11 +4862,10 @@ static struct asender_cmd asender_tbl[] = { | |||
4859 | int drbd_asender(struct drbd_thread *thi) | 4862 | int drbd_asender(struct drbd_thread *thi) |
4860 | { | 4863 | { |
4861 | struct drbd_tconn *tconn = thi->tconn; | 4864 | struct drbd_tconn *tconn = thi->tconn; |
4862 | struct p_header *h = tconn->meta.rbuf; | ||
4863 | struct asender_cmd *cmd = NULL; | 4865 | struct asender_cmd *cmd = NULL; |
4864 | struct packet_info pi; | 4866 | struct packet_info pi; |
4865 | int rv; | 4867 | int rv; |
4866 | void *buf = h; | 4868 | void *buf = tconn->meta.rbuf; |
4867 | int received = 0; | 4869 | int received = 0; |
4868 | unsigned int header_size = drbd_header_size(tconn); | 4870 | unsigned int header_size = drbd_header_size(tconn); |
4869 | int expect = header_size; | 4871 | int expect = header_size; |
@@ -4941,7 +4943,7 @@ int drbd_asender(struct drbd_thread *thi) | |||
4941 | } | 4943 | } |
4942 | 4944 | ||
4943 | if (received == expect && cmd == NULL) { | 4945 | if (received == expect && cmd == NULL) { |
4944 | if (decode_header(tconn, h, &pi)) | 4946 | if (decode_header(tconn, tconn->meta.rbuf, &pi)) |
4945 | goto reconnect; | 4947 | goto reconnect; |
4946 | cmd = &asender_tbl[pi.cmd]; | 4948 | cmd = &asender_tbl[pi.cmd]; |
4947 | if (pi.cmd >= ARRAY_SIZE(asender_tbl) || !cmd->fn) { | 4949 | if (pi.cmd >= ARRAY_SIZE(asender_tbl) || !cmd->fn) { |
@@ -4949,7 +4951,7 @@ int drbd_asender(struct drbd_thread *thi) | |||
4949 | pi.cmd, pi.size); | 4951 | pi.cmd, pi.size); |
4950 | goto disconnect; | 4952 | goto disconnect; |
4951 | } | 4953 | } |
4952 | expect = cmd->pkt_size; | 4954 | expect = header_size + cmd->pkt_size; |
4953 | if (pi.size != expect - header_size) { | 4955 | if (pi.size != expect - header_size) { |
4954 | conn_err(tconn, "Wrong packet size on meta (c: %d, l: %d)\n", | 4956 | conn_err(tconn, "Wrong packet size on meta (c: %d, l: %d)\n", |
4955 | pi.cmd, pi.size); | 4957 | pi.cmd, pi.size); |
@@ -4972,7 +4974,7 @@ int drbd_asender(struct drbd_thread *thi) | |||
4972 | if (cmd == &asender_tbl[P_PING_ACK]) | 4974 | if (cmd == &asender_tbl[P_PING_ACK]) |
4973 | ping_timeout_active = 0; | 4975 | ping_timeout_active = 0; |
4974 | 4976 | ||
4975 | buf = h; | 4977 | buf = tconn->meta.rbuf; |
4976 | received = 0; | 4978 | received = 0; |
4977 | expect = header_size; | 4979 | expect = header_size; |
4978 | cmd = NULL; | 4980 | cmd = NULL; |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 78b95e902aae..086a4b6439a7 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -1229,7 +1229,7 @@ int w_send_write_hint(struct drbd_work *w, int cancel) | |||
1229 | sock = &mdev->tconn->data; | 1229 | sock = &mdev->tconn->data; |
1230 | if (!drbd_prepare_command(mdev, sock)) | 1230 | if (!drbd_prepare_command(mdev, sock)) |
1231 | return -EIO; | 1231 | return -EIO; |
1232 | return drbd_send_command(mdev, sock, P_UNPLUG_REMOTE, sizeof(struct p_header), NULL, 0); | 1232 | return drbd_send_command(mdev, sock, P_UNPLUG_REMOTE, 0, NULL, 0); |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | int w_send_out_of_sync(struct drbd_work *w, int cancel) | 1235 | int w_send_out_of_sync(struct drbd_work *w, int cancel) |