aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/messenger.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-30 14:17:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-30 14:17:19 -0400
commitaf56e0aa35f3ae2a4c1a6d1000702df1dd78cb76 (patch)
tree304bd85e5db2d07efa2913aa7c6313b918cfbfdb /net/ceph/messenger.c
parent65a50c951a38e9827dd9655b6e686bde912e799b (diff)
parent6bd9adbdf9ca6a052b0b7455ac67b925eb38cfad (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.c182
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
656static int prepare_connect_authorizer(struct ceph_connection *con) 656static 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 */
686static void prepare_write_banner(struct ceph_messenger *msgr, 691static 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
698static int prepare_write_connect(struct ceph_messenger *msgr, 701static 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
994static int read_partial(struct ceph_connection *con, 1006static 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 */
1013static int read_partial_banner(struct ceph_connection *con) 1024static 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
1031out: 1051out:
1032 return ret; 1052 return ret;
1033} 1053}
1034 1054
1035static int read_partial_connect(struct ceph_connection *con) 1055static 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 */
1492static int read_partial_ack(struct ceph_connection *con) 1528static 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,
1627static int read_partial_message(struct ceph_connection *con) 1663static 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 */
1836static int try_write(struct ceph_connection *con) 1865static 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);