diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-30 14:17:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-30 14:17:19 -0400 |
commit | af56e0aa35f3ae2a4c1a6d1000702df1dd78cb76 (patch) | |
tree | 304bd85e5db2d07efa2913aa7c6313b918cfbfdb /net/ceph/messenger.c | |
parent | 65a50c951a38e9827dd9655b6e686bde912e799b (diff) | |
parent | 6bd9adbdf9ca6a052b0b7455ac67b925eb38cfad (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
Pull ceph updates from Sage Weil:
"There are some updates and cleanups to the CRUSH placement code, a bug
fix with incremental maps, several cleanups and fixes from Josh Durgin
in the RBD block device code, a series of cleanups and bug fixes from
Alex Elder in the messenger code, and some miscellaneous bounds
checking and gfp cleanups/fixes."
Fix up trivial conflicts in net/ceph/{messenger.c,osdmap.c} due to the
networking people preferring "unsigned int" over just "unsigned".
* git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client: (45 commits)
libceph: fix pg_temp updates
libceph: avoid unregistering osd request when not registered
ceph: add auth buf in prepare_write_connect()
ceph: rename prepare_connect_authorizer()
ceph: return pointer from prepare_connect_authorizer()
ceph: use info returned by get_authorizer
ceph: have get_authorizer methods return pointers
ceph: ensure auth ops are defined before use
ceph: messenger: reduce args to create_authorizer
ceph: define ceph_auth_handshake type
ceph: messenger: check return from get_authorizer
ceph: messenger: rework prepare_connect_authorizer()
ceph: messenger: check prepare_write_connect() result
ceph: don't set WRITE_PENDING too early
ceph: drop msgr argument from prepare_write_connect()
ceph: messenger: send banner in process_connect()
ceph: messenger: reset connection kvec caller
libceph: don't reset kvec in prepare_write_banner()
ceph: ignore preferred_osd field
ceph: fully initialize new layout
...
Diffstat (limited to 'net/ceph/messenger.c')
-rw-r--r-- | net/ceph/messenger.c | 182 |
1 files changed, 107 insertions, 75 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 36fa6bf68498..524f4e4f598b 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -653,54 +653,57 @@ static void prepare_write_keepalive(struct ceph_connection *con) | |||
653 | * Connection negotiation. | 653 | * Connection negotiation. |
654 | */ | 654 | */ |
655 | 655 | ||
656 | static int prepare_connect_authorizer(struct ceph_connection *con) | 656 | static struct ceph_auth_handshake *get_connect_authorizer(struct ceph_connection *con, |
657 | int *auth_proto) | ||
657 | { | 658 | { |
658 | void *auth_buf; | 659 | struct ceph_auth_handshake *auth; |
659 | int auth_len = 0; | 660 | |
660 | int auth_protocol = 0; | 661 | if (!con->ops->get_authorizer) { |
662 | con->out_connect.authorizer_protocol = CEPH_AUTH_UNKNOWN; | ||
663 | con->out_connect.authorizer_len = 0; | ||
664 | |||
665 | return NULL; | ||
666 | } | ||
667 | |||
668 | /* Can't hold the mutex while getting authorizer */ | ||
661 | 669 | ||
662 | mutex_unlock(&con->mutex); | 670 | mutex_unlock(&con->mutex); |
663 | if (con->ops->get_authorizer) | 671 | |
664 | con->ops->get_authorizer(con, &auth_buf, &auth_len, | 672 | auth = con->ops->get_authorizer(con, auth_proto, con->auth_retry); |
665 | &auth_protocol, &con->auth_reply_buf, | 673 | |
666 | &con->auth_reply_buf_len, | ||
667 | con->auth_retry); | ||
668 | mutex_lock(&con->mutex); | 674 | mutex_lock(&con->mutex); |
669 | 675 | ||
670 | if (test_bit(CLOSED, &con->state) || | 676 | if (IS_ERR(auth)) |
671 | test_bit(OPENING, &con->state)) | 677 | return auth; |
672 | return -EAGAIN; | 678 | if (test_bit(CLOSED, &con->state) || test_bit(OPENING, &con->state)) |
679 | return ERR_PTR(-EAGAIN); | ||
673 | 680 | ||
674 | con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol); | 681 | con->auth_reply_buf = auth->authorizer_reply_buf; |
675 | con->out_connect.authorizer_len = cpu_to_le32(auth_len); | 682 | con->auth_reply_buf_len = auth->authorizer_reply_buf_len; |
676 | 683 | ||
677 | if (auth_len) | ||
678 | ceph_con_out_kvec_add(con, auth_len, auth_buf); | ||
679 | 684 | ||
680 | return 0; | 685 | return auth; |
681 | } | 686 | } |
682 | 687 | ||
683 | /* | 688 | /* |
684 | * We connected to a peer and are saying hello. | 689 | * We connected to a peer and are saying hello. |
685 | */ | 690 | */ |
686 | static void prepare_write_banner(struct ceph_messenger *msgr, | 691 | static void prepare_write_banner(struct ceph_connection *con) |
687 | struct ceph_connection *con) | ||
688 | { | 692 | { |
689 | ceph_con_out_kvec_reset(con); | ||
690 | ceph_con_out_kvec_add(con, strlen(CEPH_BANNER), CEPH_BANNER); | 693 | ceph_con_out_kvec_add(con, strlen(CEPH_BANNER), CEPH_BANNER); |
691 | ceph_con_out_kvec_add(con, sizeof (msgr->my_enc_addr), | 694 | ceph_con_out_kvec_add(con, sizeof (con->msgr->my_enc_addr), |
692 | &msgr->my_enc_addr); | 695 | &con->msgr->my_enc_addr); |
693 | 696 | ||
694 | con->out_more = 0; | 697 | con->out_more = 0; |
695 | set_bit(WRITE_PENDING, &con->state); | 698 | set_bit(WRITE_PENDING, &con->state); |
696 | } | 699 | } |
697 | 700 | ||
698 | static int prepare_write_connect(struct ceph_messenger *msgr, | 701 | static int prepare_write_connect(struct ceph_connection *con) |
699 | struct ceph_connection *con, | ||
700 | int include_banner) | ||
701 | { | 702 | { |
702 | unsigned int global_seq = get_global_seq(con->msgr, 0); | 703 | unsigned int global_seq = get_global_seq(con->msgr, 0); |
703 | int proto; | 704 | int proto; |
705 | int auth_proto; | ||
706 | struct ceph_auth_handshake *auth; | ||
704 | 707 | ||
705 | switch (con->peer_name.type) { | 708 | switch (con->peer_name.type) { |
706 | case CEPH_ENTITY_TYPE_MON: | 709 | case CEPH_ENTITY_TYPE_MON: |
@@ -719,23 +722,32 @@ static int prepare_write_connect(struct ceph_messenger *msgr, | |||
719 | dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, | 722 | dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, |
720 | con->connect_seq, global_seq, proto); | 723 | con->connect_seq, global_seq, proto); |
721 | 724 | ||
722 | con->out_connect.features = cpu_to_le64(msgr->supported_features); | 725 | con->out_connect.features = cpu_to_le64(con->msgr->supported_features); |
723 | con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); | 726 | con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); |
724 | con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); | 727 | con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); |
725 | con->out_connect.global_seq = cpu_to_le32(global_seq); | 728 | con->out_connect.global_seq = cpu_to_le32(global_seq); |
726 | con->out_connect.protocol_version = cpu_to_le32(proto); | 729 | con->out_connect.protocol_version = cpu_to_le32(proto); |
727 | con->out_connect.flags = 0; | 730 | con->out_connect.flags = 0; |
728 | 731 | ||
729 | if (include_banner) | 732 | auth_proto = CEPH_AUTH_UNKNOWN; |
730 | prepare_write_banner(msgr, con); | 733 | auth = get_connect_authorizer(con, &auth_proto); |
731 | else | 734 | if (IS_ERR(auth)) |
732 | ceph_con_out_kvec_reset(con); | 735 | return PTR_ERR(auth); |
733 | ceph_con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect); | 736 | |
737 | con->out_connect.authorizer_protocol = cpu_to_le32(auth_proto); | ||
738 | con->out_connect.authorizer_len = auth ? | ||
739 | cpu_to_le32(auth->authorizer_buf_len) : 0; | ||
740 | |||
741 | ceph_con_out_kvec_add(con, sizeof (con->out_connect), | ||
742 | &con->out_connect); | ||
743 | if (auth && auth->authorizer_buf_len) | ||
744 | ceph_con_out_kvec_add(con, auth->authorizer_buf_len, | ||
745 | auth->authorizer_buf); | ||
734 | 746 | ||
735 | con->out_more = 0; | 747 | con->out_more = 0; |
736 | set_bit(WRITE_PENDING, &con->state); | 748 | set_bit(WRITE_PENDING, &con->state); |
737 | 749 | ||
738 | return prepare_connect_authorizer(con); | 750 | return 0; |
739 | } | 751 | } |
740 | 752 | ||
741 | /* | 753 | /* |
@@ -992,11 +1004,10 @@ static int prepare_read_message(struct ceph_connection *con) | |||
992 | 1004 | ||
993 | 1005 | ||
994 | static int read_partial(struct ceph_connection *con, | 1006 | static int read_partial(struct ceph_connection *con, |
995 | int *to, int size, void *object) | 1007 | int end, int size, void *object) |
996 | { | 1008 | { |
997 | *to += size; | 1009 | while (con->in_base_pos < end) { |
998 | while (con->in_base_pos < *to) { | 1010 | int left = end - con->in_base_pos; |
999 | int left = *to - con->in_base_pos; | ||
1000 | int have = size - left; | 1011 | int have = size - left; |
1001 | int ret = ceph_tcp_recvmsg(con->sock, object + have, left); | 1012 | int ret = ceph_tcp_recvmsg(con->sock, object + have, left); |
1002 | if (ret <= 0) | 1013 | if (ret <= 0) |
@@ -1012,37 +1023,52 @@ static int read_partial(struct ceph_connection *con, | |||
1012 | */ | 1023 | */ |
1013 | static int read_partial_banner(struct ceph_connection *con) | 1024 | static int read_partial_banner(struct ceph_connection *con) |
1014 | { | 1025 | { |
1015 | int ret, to = 0; | 1026 | int size; |
1027 | int end; | ||
1028 | int ret; | ||
1016 | 1029 | ||
1017 | dout("read_partial_banner %p at %d\n", con, con->in_base_pos); | 1030 | dout("read_partial_banner %p at %d\n", con, con->in_base_pos); |
1018 | 1031 | ||
1019 | /* peer's banner */ | 1032 | /* peer's banner */ |
1020 | ret = read_partial(con, &to, strlen(CEPH_BANNER), con->in_banner); | 1033 | size = strlen(CEPH_BANNER); |
1034 | end = size; | ||
1035 | ret = read_partial(con, end, size, con->in_banner); | ||
1021 | if (ret <= 0) | 1036 | if (ret <= 0) |
1022 | goto out; | 1037 | goto out; |
1023 | ret = read_partial(con, &to, sizeof(con->actual_peer_addr), | 1038 | |
1024 | &con->actual_peer_addr); | 1039 | size = sizeof (con->actual_peer_addr); |
1040 | end += size; | ||
1041 | ret = read_partial(con, end, size, &con->actual_peer_addr); | ||
1025 | if (ret <= 0) | 1042 | if (ret <= 0) |
1026 | goto out; | 1043 | goto out; |
1027 | ret = read_partial(con, &to, sizeof(con->peer_addr_for_me), | 1044 | |
1028 | &con->peer_addr_for_me); | 1045 | size = sizeof (con->peer_addr_for_me); |
1046 | end += size; | ||
1047 | ret = read_partial(con, end, size, &con->peer_addr_for_me); | ||
1029 | if (ret <= 0) | 1048 | if (ret <= 0) |
1030 | goto out; | 1049 | goto out; |
1050 | |||
1031 | out: | 1051 | out: |
1032 | return ret; | 1052 | return ret; |
1033 | } | 1053 | } |
1034 | 1054 | ||
1035 | static int read_partial_connect(struct ceph_connection *con) | 1055 | static int read_partial_connect(struct ceph_connection *con) |
1036 | { | 1056 | { |
1037 | int ret, to = 0; | 1057 | int size; |
1058 | int end; | ||
1059 | int ret; | ||
1038 | 1060 | ||
1039 | dout("read_partial_connect %p at %d\n", con, con->in_base_pos); | 1061 | dout("read_partial_connect %p at %d\n", con, con->in_base_pos); |
1040 | 1062 | ||
1041 | ret = read_partial(con, &to, sizeof(con->in_reply), &con->in_reply); | 1063 | size = sizeof (con->in_reply); |
1064 | end = size; | ||
1065 | ret = read_partial(con, end, size, &con->in_reply); | ||
1042 | if (ret <= 0) | 1066 | if (ret <= 0) |
1043 | goto out; | 1067 | goto out; |
1044 | ret = read_partial(con, &to, le32_to_cpu(con->in_reply.authorizer_len), | 1068 | |
1045 | con->auth_reply_buf); | 1069 | size = le32_to_cpu(con->in_reply.authorizer_len); |
1070 | end += size; | ||
1071 | ret = read_partial(con, end, size, con->auth_reply_buf); | ||
1046 | if (ret <= 0) | 1072 | if (ret <= 0) |
1047 | goto out; | 1073 | goto out; |
1048 | 1074 | ||
@@ -1377,7 +1403,8 @@ static int process_connect(struct ceph_connection *con) | |||
1377 | return -1; | 1403 | return -1; |
1378 | } | 1404 | } |
1379 | con->auth_retry = 1; | 1405 | con->auth_retry = 1; |
1380 | ret = prepare_write_connect(con->msgr, con, 0); | 1406 | ceph_con_out_kvec_reset(con); |
1407 | ret = prepare_write_connect(con); | ||
1381 | if (ret < 0) | 1408 | if (ret < 0) |
1382 | return ret; | 1409 | return ret; |
1383 | prepare_read_connect(con); | 1410 | prepare_read_connect(con); |
@@ -1397,7 +1424,10 @@ static int process_connect(struct ceph_connection *con) | |||
1397 | ENTITY_NAME(con->peer_name), | 1424 | ENTITY_NAME(con->peer_name), |
1398 | ceph_pr_addr(&con->peer_addr.in_addr)); | 1425 | ceph_pr_addr(&con->peer_addr.in_addr)); |
1399 | reset_connection(con); | 1426 | reset_connection(con); |
1400 | prepare_write_connect(con->msgr, con, 0); | 1427 | ceph_con_out_kvec_reset(con); |
1428 | ret = prepare_write_connect(con); | ||
1429 | if (ret < 0) | ||
1430 | return ret; | ||
1401 | prepare_read_connect(con); | 1431 | prepare_read_connect(con); |
1402 | 1432 | ||
1403 | /* Tell ceph about it. */ | 1433 | /* Tell ceph about it. */ |
@@ -1420,7 +1450,10 @@ static int process_connect(struct ceph_connection *con) | |||
1420 | le32_to_cpu(con->out_connect.connect_seq), | 1450 | le32_to_cpu(con->out_connect.connect_seq), |
1421 | le32_to_cpu(con->in_connect.connect_seq)); | 1451 | le32_to_cpu(con->in_connect.connect_seq)); |
1422 | con->connect_seq = le32_to_cpu(con->in_connect.connect_seq); | 1452 | con->connect_seq = le32_to_cpu(con->in_connect.connect_seq); |
1423 | prepare_write_connect(con->msgr, con, 0); | 1453 | ceph_con_out_kvec_reset(con); |
1454 | ret = prepare_write_connect(con); | ||
1455 | if (ret < 0) | ||
1456 | return ret; | ||
1424 | prepare_read_connect(con); | 1457 | prepare_read_connect(con); |
1425 | break; | 1458 | break; |
1426 | 1459 | ||
@@ -1434,7 +1467,10 @@ static int process_connect(struct ceph_connection *con) | |||
1434 | le32_to_cpu(con->in_connect.global_seq)); | 1467 | le32_to_cpu(con->in_connect.global_seq)); |
1435 | get_global_seq(con->msgr, | 1468 | get_global_seq(con->msgr, |
1436 | le32_to_cpu(con->in_connect.global_seq)); | 1469 | le32_to_cpu(con->in_connect.global_seq)); |
1437 | prepare_write_connect(con->msgr, con, 0); | 1470 | ceph_con_out_kvec_reset(con); |
1471 | ret = prepare_write_connect(con); | ||
1472 | if (ret < 0) | ||
1473 | return ret; | ||
1438 | prepare_read_connect(con); | 1474 | prepare_read_connect(con); |
1439 | break; | 1475 | break; |
1440 | 1476 | ||
@@ -1491,10 +1527,10 @@ static int process_connect(struct ceph_connection *con) | |||
1491 | */ | 1527 | */ |
1492 | static int read_partial_ack(struct ceph_connection *con) | 1528 | static int read_partial_ack(struct ceph_connection *con) |
1493 | { | 1529 | { |
1494 | int to = 0; | 1530 | int size = sizeof (con->in_temp_ack); |
1531 | int end = size; | ||
1495 | 1532 | ||
1496 | return read_partial(con, &to, sizeof(con->in_temp_ack), | 1533 | return read_partial(con, end, size, &con->in_temp_ack); |
1497 | &con->in_temp_ack); | ||
1498 | } | 1534 | } |
1499 | 1535 | ||
1500 | 1536 | ||
@@ -1627,8 +1663,9 @@ static int read_partial_message_bio(struct ceph_connection *con, | |||
1627 | static int read_partial_message(struct ceph_connection *con) | 1663 | static int read_partial_message(struct ceph_connection *con) |
1628 | { | 1664 | { |
1629 | struct ceph_msg *m = con->in_msg; | 1665 | struct ceph_msg *m = con->in_msg; |
1666 | int size; | ||
1667 | int end; | ||
1630 | int ret; | 1668 | int ret; |
1631 | int to, left; | ||
1632 | unsigned int front_len, middle_len, data_len; | 1669 | unsigned int front_len, middle_len, data_len; |
1633 | bool do_datacrc = !con->msgr->nocrc; | 1670 | bool do_datacrc = !con->msgr->nocrc; |
1634 | int skip; | 1671 | int skip; |
@@ -1638,15 +1675,11 @@ static int read_partial_message(struct ceph_connection *con) | |||
1638 | dout("read_partial_message con %p msg %p\n", con, m); | 1675 | dout("read_partial_message con %p msg %p\n", con, m); |
1639 | 1676 | ||
1640 | /* header */ | 1677 | /* header */ |
1641 | while (con->in_base_pos < sizeof(con->in_hdr)) { | 1678 | size = sizeof (con->in_hdr); |
1642 | left = sizeof(con->in_hdr) - con->in_base_pos; | 1679 | end = size; |
1643 | ret = ceph_tcp_recvmsg(con->sock, | 1680 | ret = read_partial(con, end, size, &con->in_hdr); |
1644 | (char *)&con->in_hdr + con->in_base_pos, | 1681 | if (ret <= 0) |
1645 | left); | 1682 | return ret; |
1646 | if (ret <= 0) | ||
1647 | return ret; | ||
1648 | con->in_base_pos += ret; | ||
1649 | } | ||
1650 | 1683 | ||
1651 | crc = crc32c(0, &con->in_hdr, offsetof(struct ceph_msg_header, crc)); | 1684 | crc = crc32c(0, &con->in_hdr, offsetof(struct ceph_msg_header, crc)); |
1652 | if (cpu_to_le32(crc) != con->in_hdr.crc) { | 1685 | if (cpu_to_le32(crc) != con->in_hdr.crc) { |
@@ -1759,16 +1792,12 @@ static int read_partial_message(struct ceph_connection *con) | |||
1759 | } | 1792 | } |
1760 | 1793 | ||
1761 | /* footer */ | 1794 | /* footer */ |
1762 | to = sizeof(m->hdr) + sizeof(m->footer); | 1795 | size = sizeof (m->footer); |
1763 | while (con->in_base_pos < to) { | 1796 | end += size; |
1764 | left = to - con->in_base_pos; | 1797 | ret = read_partial(con, end, size, &m->footer); |
1765 | ret = ceph_tcp_recvmsg(con->sock, (char *)&m->footer + | 1798 | if (ret <= 0) |
1766 | (con->in_base_pos - sizeof(m->hdr)), | 1799 | return ret; |
1767 | left); | 1800 | |
1768 | if (ret <= 0) | ||
1769 | return ret; | ||
1770 | con->in_base_pos += ret; | ||
1771 | } | ||
1772 | dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n", | 1801 | dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n", |
1773 | m, front_len, m->footer.front_crc, middle_len, | 1802 | m, front_len, m->footer.front_crc, middle_len, |
1774 | m->footer.middle_crc, data_len, m->footer.data_crc); | 1803 | m->footer.middle_crc, data_len, m->footer.data_crc); |
@@ -1835,7 +1864,6 @@ static void process_message(struct ceph_connection *con) | |||
1835 | */ | 1864 | */ |
1836 | static int try_write(struct ceph_connection *con) | 1865 | static int try_write(struct ceph_connection *con) |
1837 | { | 1866 | { |
1838 | struct ceph_messenger *msgr = con->msgr; | ||
1839 | int ret = 1; | 1867 | int ret = 1; |
1840 | 1868 | ||
1841 | dout("try_write start %p state %lu nref %d\n", con, con->state, | 1869 | dout("try_write start %p state %lu nref %d\n", con, con->state, |
@@ -1846,7 +1874,11 @@ more: | |||
1846 | 1874 | ||
1847 | /* open the socket first? */ | 1875 | /* open the socket first? */ |
1848 | if (con->sock == NULL) { | 1876 | if (con->sock == NULL) { |
1849 | prepare_write_connect(msgr, con, 1); | 1877 | ceph_con_out_kvec_reset(con); |
1878 | prepare_write_banner(con); | ||
1879 | ret = prepare_write_connect(con); | ||
1880 | if (ret < 0) | ||
1881 | goto out; | ||
1850 | prepare_read_banner(con); | 1882 | prepare_read_banner(con); |
1851 | set_bit(CONNECTING, &con->state); | 1883 | set_bit(CONNECTING, &con->state); |
1852 | clear_bit(NEGOTIATING, &con->state); | 1884 | clear_bit(NEGOTIATING, &con->state); |