--- /dev/null
+From 5b26309b3c8225efba57a23a52b31d8ec39b1358 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Thu, 10 May 2012 10:29:50 -0500
+Subject: ceph: messenger: change read_partial() to take "end" arg
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit fd51653f78cf40a0516e521b6de22f329c5bad8d)
+
+Make the second argument to read_partial() be the ending input byte
+position rather than the beginning offset it now represents. This
+amounts to moving the addition "to + size" into the caller.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 60 ++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 38 insertions(+), 22 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -992,10 +992,8 @@ static int prepare_read_message(struct c
+
+
+ static int read_partial(struct ceph_connection *con,
+- int to, int size, void *object)
++ int end, int size, void *object)
+ {
+- int end = to + size;
+-
+ while (con->in_base_pos < end) {
+ int left = end - con->in_base_pos;
+ int have = size - left;
+@@ -1013,40 +1011,52 @@ static int read_partial(struct ceph_conn
+ */
+ static int read_partial_banner(struct ceph_connection *con)
+ {
+- int ret, to = 0;
++ int size;
++ int end;
++ int ret;
+
+ dout("read_partial_banner %p at %d\n", con, con->in_base_pos);
+
+ /* peer's banner */
+- ret = read_partial(con, to, strlen(CEPH_BANNER), con->in_banner);
++ size = strlen(CEPH_BANNER);
++ end = size;
++ ret = read_partial(con, end, size, con->in_banner);
+ if (ret <= 0)
+ goto out;
+- to += strlen(CEPH_BANNER);
+- ret = read_partial(con, to, sizeof(con->actual_peer_addr),
+- &con->actual_peer_addr);
++
++ size = sizeof (con->actual_peer_addr);
++ end += size;
++ ret = read_partial(con, end, size, &con->actual_peer_addr);
+ if (ret <= 0)
+ goto out;
+- to += sizeof(con->actual_peer_addr);
+- ret = read_partial(con, to, sizeof(con->peer_addr_for_me),
+- &con->peer_addr_for_me);
++
++ size = sizeof (con->peer_addr_for_me);
++ end += size;
++ ret = read_partial(con, end, size, &con->peer_addr_for_me);
+ if (ret <= 0)
+ goto out;
++
+ out:
+ return ret;
+ }
+
+ static int read_partial_connect(struct ceph_connection *con)
+ {
+- int ret, to = 0;
++ int size;
++ int end;
++ int ret;
+
+ dout("read_partial_connect %p at %d\n", con, con->in_base_pos);
+
+- ret = read_partial(con, to, sizeof(con->in_reply), &con->in_reply);
++ size = sizeof (con->in_reply);
++ end = size;
++ ret = read_partial(con, end, size, &con->in_reply);
+ if (ret <= 0)
+ goto out;
+- to += sizeof(con->in_reply);
+- ret = read_partial(con, to, le32_to_cpu(con->in_reply.authorizer_len),
+- con->auth_reply_buf);
++
++ size = le32_to_cpu(con->in_reply.authorizer_len);
++ end += size;
++ ret = read_partial(con, end, size, con->auth_reply_buf);
+ if (ret <= 0)
+ goto out;
+
+@@ -1495,8 +1505,10 @@ static int process_connect(struct ceph_c
+ */
+ static int read_partial_ack(struct ceph_connection *con)
+ {
+- return read_partial(con, 0, sizeof(con->in_temp_ack),
+- &con->in_temp_ack);
++ int size = sizeof (con->in_temp_ack);
++ int end = size;
++
++ return read_partial(con, end, size, &con->in_temp_ack);
+ }
+
+
+@@ -1629,8 +1641,9 @@ static int read_partial_message_bio(stru
+ static int read_partial_message(struct ceph_connection *con)
+ {
+ struct ceph_msg *m = con->in_msg;
++ int size;
++ int end;
+ int ret;
+- int to;
+ unsigned front_len, middle_len, data_len;
+ bool do_datacrc = !con->msgr->nocrc;
+ int skip;
+@@ -1640,7 +1653,9 @@ static int read_partial_message(struct c
+ dout("read_partial_message con %p msg %p\n", con, m);
+
+ /* header */
+- ret = read_partial(con, 0, sizeof (con->in_hdr), &con->in_hdr);
++ size = sizeof (con->in_hdr);
++ end = size;
++ ret = read_partial(con, end, size, &con->in_hdr);
+ if (ret <= 0)
+ return ret;
+
+@@ -1755,8 +1770,9 @@ static int read_partial_message(struct c
+ }
+
+ /* footer */
+- to = sizeof (m->hdr);
+- ret = read_partial(con, to, sizeof (m->footer), &m->footer);
++ size = sizeof (m->footer);
++ end += size;
++ ret = read_partial(con, end, size, &m->footer);
+ if (ret <= 0)
+ return ret;
+
--- /dev/null
+From 4dc97cba04902b40aec556f1254ed2d6e7c98920 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: libceph: don't reset kvec in prepare_write_banner()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit d329156f16306449c273002486c28de3ddddfd89)
+
+Move the kvec reset for a connection out of prepare_write_banner and
+into its only caller.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -686,7 +686,6 @@ static int prepare_connect_authorizer(st
+ static void prepare_write_banner(struct ceph_messenger *msgr,
+ struct ceph_connection *con)
+ {
+- ceph_con_out_kvec_reset(con);
+ ceph_con_out_kvec_add(con, strlen(CEPH_BANNER), CEPH_BANNER);
+ ceph_con_out_kvec_add(con, sizeof (msgr->my_enc_addr),
+ &msgr->my_enc_addr);
+@@ -726,10 +725,9 @@ static int prepare_write_connect(struct
+ con->out_connect.protocol_version = cpu_to_le32(proto);
+ con->out_connect.flags = 0;
+
++ ceph_con_out_kvec_reset(con);
+ if (include_banner)
+ prepare_write_banner(msgr, con);
+- else
+- ceph_con_out_kvec_reset(con);
+ ceph_con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect);
+
+ con->out_more = 0;
--- /dev/null
+From 4650b720da42507c0654908b6e2d215359944fff Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: ceph: messenger: reset connection kvec caller
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 84fb3adf6413862cff51d8af3fce5f0b655586a2)
+
+Reset a connection's kvec fields in the caller rather than in
+prepare_write_connect(). This ends up repeating a few lines of
+code but it's improving the separation between distinct operations
+on the connection, which we can take advantage of later.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -725,7 +725,6 @@ static int prepare_write_connect(struct
+ con->out_connect.protocol_version = cpu_to_le32(proto);
+ con->out_connect.flags = 0;
+
+- ceph_con_out_kvec_reset(con);
+ if (include_banner)
+ prepare_write_banner(msgr, con);
+ ceph_con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect);
+@@ -1389,6 +1388,7 @@ static int process_connect(struct ceph_c
+ return -1;
+ }
+ con->auth_retry = 1;
++ ceph_con_out_kvec_reset(con);
+ ret = prepare_write_connect(con->msgr, con, 0);
+ if (ret < 0)
+ return ret;
+@@ -1409,6 +1409,7 @@ static int process_connect(struct ceph_c
+ ENTITY_NAME(con->peer_name),
+ ceph_pr_addr(&con->peer_addr.in_addr));
+ reset_connection(con);
++ ceph_con_out_kvec_reset(con);
+ prepare_write_connect(con->msgr, con, 0);
+ prepare_read_connect(con);
+
+@@ -1432,6 +1433,7 @@ static int process_connect(struct ceph_c
+ le32_to_cpu(con->out_connect.connect_seq),
+ le32_to_cpu(con->in_connect.connect_seq));
+ con->connect_seq = le32_to_cpu(con->in_connect.connect_seq);
++ ceph_con_out_kvec_reset(con);
+ prepare_write_connect(con->msgr, con, 0);
+ prepare_read_connect(con);
+ break;
+@@ -1446,6 +1448,7 @@ static int process_connect(struct ceph_c
+ le32_to_cpu(con->in_connect.global_seq));
+ get_global_seq(con->msgr,
+ le32_to_cpu(con->in_connect.global_seq));
++ ceph_con_out_kvec_reset(con);
+ prepare_write_connect(con->msgr, con, 0);
+ prepare_read_connect(con);
+ break;
+@@ -1851,6 +1854,7 @@ more:
+
+ /* open the socket first? */
+ if (con->sock == NULL) {
++ ceph_con_out_kvec_reset(con);
+ prepare_write_connect(msgr, con, 1);
+ prepare_read_banner(con);
+ set_bit(CONNECTING, &con->state);
--- /dev/null
+From aa71fe2d3296e900b0bb70bf8ed2a752e83e1f4b Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: ceph: messenger: send banner in process_connect()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 41b90c00858129f52d08e6a05c9cfdb0f2bd074d)
+
+prepare_write_connect() has an argument indicating whether a banner
+should be sent out before sending out a connection message. It's
+only ever set in one of its callers, so move the code that arranges
+to send the banner into that caller and drop the "include_banner"
+argument from prepare_write_connect().
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -695,8 +695,7 @@ static void prepare_write_banner(struct
+ }
+
+ static int prepare_write_connect(struct ceph_messenger *msgr,
+- struct ceph_connection *con,
+- int include_banner)
++ struct ceph_connection *con)
+ {
+ unsigned global_seq = get_global_seq(con->msgr, 0);
+ int proto;
+@@ -725,8 +724,6 @@ static int prepare_write_connect(struct
+ con->out_connect.protocol_version = cpu_to_le32(proto);
+ con->out_connect.flags = 0;
+
+- if (include_banner)
+- prepare_write_banner(msgr, con);
+ ceph_con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect);
+
+ con->out_more = 0;
+@@ -1389,7 +1386,7 @@ static int process_connect(struct ceph_c
+ }
+ con->auth_retry = 1;
+ ceph_con_out_kvec_reset(con);
+- ret = prepare_write_connect(con->msgr, con, 0);
++ ret = prepare_write_connect(con->msgr, con);
+ if (ret < 0)
+ return ret;
+ prepare_read_connect(con);
+@@ -1410,7 +1407,7 @@ static int process_connect(struct ceph_c
+ ceph_pr_addr(&con->peer_addr.in_addr));
+ reset_connection(con);
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con->msgr, con, 0);
++ prepare_write_connect(con->msgr, con);
+ prepare_read_connect(con);
+
+ /* Tell ceph about it. */
+@@ -1434,7 +1431,7 @@ static int process_connect(struct ceph_c
+ le32_to_cpu(con->in_connect.connect_seq));
+ con->connect_seq = le32_to_cpu(con->in_connect.connect_seq);
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con->msgr, con, 0);
++ prepare_write_connect(con->msgr, con);
+ prepare_read_connect(con);
+ break;
+
+@@ -1449,7 +1446,7 @@ static int process_connect(struct ceph_c
+ get_global_seq(con->msgr,
+ le32_to_cpu(con->in_connect.global_seq));
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con->msgr, con, 0);
++ prepare_write_connect(con->msgr, con);
+ prepare_read_connect(con);
+ break;
+
+@@ -1855,7 +1852,8 @@ more:
+ /* open the socket first? */
+ if (con->sock == NULL) {
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(msgr, con, 1);
++ prepare_write_banner(msgr, con);
++ prepare_write_connect(msgr, con);
+ prepare_read_banner(con);
+ set_bit(CONNECTING, &con->state);
+ clear_bit(NEGOTIATING, &con->state);
--- /dev/null
+From a2f568816dee0c0901c4a3e03f5c6e79d3771461 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: ceph: drop msgr argument from prepare_write_connect()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit e825a66df97776d30a48a187e3a986736af43945)
+
+In all cases, the value passed as the msgr argument to
+prepare_write_connect() is just con->msgr. Just get the msgr
+value from the ceph connection and drop the unneeded argument.
+
+The only msgr passed to prepare_write_banner() is also therefore
+just the one from con->msgr, so change that function to drop the
+msgr argument as well.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -683,19 +683,17 @@ static int prepare_connect_authorizer(st
+ /*
+ * We connected to a peer and are saying hello.
+ */
+-static void prepare_write_banner(struct ceph_messenger *msgr,
+- struct ceph_connection *con)
++static void prepare_write_banner(struct ceph_connection *con)
+ {
+ ceph_con_out_kvec_add(con, strlen(CEPH_BANNER), CEPH_BANNER);
+- ceph_con_out_kvec_add(con, sizeof (msgr->my_enc_addr),
+- &msgr->my_enc_addr);
++ ceph_con_out_kvec_add(con, sizeof (con->msgr->my_enc_addr),
++ &con->msgr->my_enc_addr);
+
+ con->out_more = 0;
+ set_bit(WRITE_PENDING, &con->state);
+ }
+
+-static int prepare_write_connect(struct ceph_messenger *msgr,
+- struct ceph_connection *con)
++static int prepare_write_connect(struct ceph_connection *con)
+ {
+ unsigned global_seq = get_global_seq(con->msgr, 0);
+ int proto;
+@@ -717,7 +715,7 @@ static int prepare_write_connect(struct
+ dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
+ con->connect_seq, global_seq, proto);
+
+- con->out_connect.features = cpu_to_le64(msgr->supported_features);
++ con->out_connect.features = cpu_to_le64(con->msgr->supported_features);
+ con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
+ con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
+ con->out_connect.global_seq = cpu_to_le32(global_seq);
+@@ -1386,7 +1384,7 @@ static int process_connect(struct ceph_c
+ }
+ con->auth_retry = 1;
+ ceph_con_out_kvec_reset(con);
+- ret = prepare_write_connect(con->msgr, con);
++ ret = prepare_write_connect(con);
+ if (ret < 0)
+ return ret;
+ prepare_read_connect(con);
+@@ -1407,7 +1405,7 @@ static int process_connect(struct ceph_c
+ ceph_pr_addr(&con->peer_addr.in_addr));
+ reset_connection(con);
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con->msgr, con);
++ prepare_write_connect(con);
+ prepare_read_connect(con);
+
+ /* Tell ceph about it. */
+@@ -1431,7 +1429,7 @@ static int process_connect(struct ceph_c
+ le32_to_cpu(con->in_connect.connect_seq));
+ con->connect_seq = le32_to_cpu(con->in_connect.connect_seq);
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con->msgr, con);
++ prepare_write_connect(con);
+ prepare_read_connect(con);
+ break;
+
+@@ -1446,7 +1444,7 @@ static int process_connect(struct ceph_c
+ get_global_seq(con->msgr,
+ le32_to_cpu(con->in_connect.global_seq));
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con->msgr, con);
++ prepare_write_connect(con);
+ prepare_read_connect(con);
+ break;
+
+@@ -1840,7 +1838,6 @@ static void process_message(struct ceph_
+ */
+ static int try_write(struct ceph_connection *con)
+ {
+- struct ceph_messenger *msgr = con->msgr;
+ int ret = 1;
+
+ dout("try_write start %p state %lu nref %d\n", con, con->state,
+@@ -1852,8 +1849,8 @@ more:
+ /* open the socket first? */
+ if (con->sock == NULL) {
+ ceph_con_out_kvec_reset(con);
+- prepare_write_banner(msgr, con);
+- prepare_write_connect(msgr, con);
++ prepare_write_banner(con);
++ prepare_write_connect(con);
+ prepare_read_banner(con);
+ set_bit(CONNECTING, &con->state);
+ clear_bit(NEGOTIATING, &con->state);
--- /dev/null
+From 3e08e618d1d9f0274934abda1874f62eaaa044ce Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: ceph: don't set WRITE_PENDING too early
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit e10c758e4031a801ea4d2f8fb39bf14c2658d74b)
+
+prepare_write_connect() prepares a connect message, then sets
+WRITE_PENDING on the connection. Then *after* this, it calls
+prepare_connect_authorizer(), which updates the content of the
+connection buffer already queued for sending. It's also possible it
+will result in prepare_write_connect() returning -EAGAIN despite the
+WRITE_PENDING big getting set.
+
+Fix this by preparing the connect authorizer first, setting the
+WRITE_PENDING bit only after that is done.
+
+Partially addresses http://tracker.newdream.net/issues/2424
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -697,6 +697,7 @@ static int prepare_write_connect(struct
+ {
+ unsigned global_seq = get_global_seq(con->msgr, 0);
+ int proto;
++ int ret;
+
+ switch (con->peer_name.type) {
+ case CEPH_ENTITY_TYPE_MON:
+@@ -723,11 +724,14 @@ static int prepare_write_connect(struct
+ con->out_connect.flags = 0;
+
+ ceph_con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect);
++ ret = prepare_connect_authorizer(con);
++ if (ret)
++ return ret;
+
+ con->out_more = 0;
+ set_bit(WRITE_PENDING, &con->state);
+
+- return prepare_connect_authorizer(con);
++ return 0;
+ }
+
+ /*
--- /dev/null
+From bb74b21bbf82fe45ded39d0e5138a7a4fa48b513 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 21:51:59 -0500
+Subject: ceph: messenger: check prepare_write_connect() result
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 5a0f8fdd8a0ebe320952a388331dc043d7e14ced)
+
+prepare_write_connect() can return an error, but only one of its
+callers checks for it. All the rest are in functions that already
+return errors, so it should be fine to return the error if one
+gets returned.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -1409,7 +1409,9 @@ static int process_connect(struct ceph_c
+ ceph_pr_addr(&con->peer_addr.in_addr));
+ reset_connection(con);
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con);
++ ret = prepare_write_connect(con);
++ if (ret < 0)
++ return ret;
+ prepare_read_connect(con);
+
+ /* Tell ceph about it. */
+@@ -1433,7 +1435,9 @@ static int process_connect(struct ceph_c
+ le32_to_cpu(con->in_connect.connect_seq));
+ con->connect_seq = le32_to_cpu(con->in_connect.connect_seq);
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con);
++ ret = prepare_write_connect(con);
++ if (ret < 0)
++ return ret;
+ prepare_read_connect(con);
+ break;
+
+@@ -1448,7 +1452,9 @@ static int process_connect(struct ceph_c
+ get_global_seq(con->msgr,
+ le32_to_cpu(con->in_connect.global_seq));
+ ceph_con_out_kvec_reset(con);
+- prepare_write_connect(con);
++ ret = prepare_write_connect(con);
++ if (ret < 0)
++ return ret;
+ prepare_read_connect(con);
+ break;
+
+@@ -1854,7 +1860,9 @@ more:
+ if (con->sock == NULL) {
+ ceph_con_out_kvec_reset(con);
+ prepare_write_banner(con);
+- prepare_write_connect(con);
++ ret = prepare_write_connect(con);
++ if (ret < 0)
++ goto out;
+ prepare_read_banner(con);
+ set_bit(CONNECTING, &con->state);
+ clear_bit(NEGOTIATING, &con->state);
--- /dev/null
+From f184c9fd656b27adcb0a74069c8373a1759465d1 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: ceph: messenger: rework prepare_connect_authorizer()
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit b1c6b9803f5491e94041e6da96bc9dec3870e792)
+
+Change prepare_connect_authorizer() so it returns without dropping
+the connection mutex if the connection has no get_authorizer method.
+
+Use the symbolic CEPH_AUTH_UNKNOWN instead of 0 when assigning
+authorization protocols.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -656,19 +656,29 @@ static void prepare_write_keepalive(stru
+ static int prepare_connect_authorizer(struct ceph_connection *con)
+ {
+ void *auth_buf;
+- int auth_len = 0;
+- int auth_protocol = 0;
++ int auth_len;
++ int auth_protocol;
++
++ if (!con->ops->get_authorizer) {
++ con->out_connect.authorizer_protocol = CEPH_AUTH_UNKNOWN;
++ con->out_connect.authorizer_len = 0;
++
++ return 0;
++ }
++
++ /* Can't hold the mutex while getting authorizer */
+
+ mutex_unlock(&con->mutex);
+- if (con->ops->get_authorizer)
+- con->ops->get_authorizer(con, &auth_buf, &auth_len,
+- &auth_protocol, &con->auth_reply_buf,
+- &con->auth_reply_buf_len,
+- con->auth_retry);
++
++ auth_buf = NULL;
++ auth_len = 0;
++ auth_protocol = CEPH_AUTH_UNKNOWN;
++ con->ops->get_authorizer(con, &auth_buf, &auth_len, &auth_protocol,
++ &con->auth_reply_buf, &con->auth_reply_buf_len,
++ con->auth_retry);
+ mutex_lock(&con->mutex);
+
+- if (test_bit(CLOSED, &con->state) ||
+- test_bit(OPENING, &con->state))
++ if (test_bit(CLOSED, &con->state) || test_bit(OPENING, &con->state))
+ return -EAGAIN;
+
+ con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol);
--- /dev/null
+From 6fb5002e461dd8e8f6fe39c940d52b3320f16753 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: ceph: messenger: check return from get_authorizer
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit ed96af646011412c2bf1ffe860db170db355fae5)
+
+In prepare_connect_authorizer(), a connection's get_authorizer
+method is called but ignores its return value. This function can
+return an error, so check for it and return it if that ever occurs.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ceph/messenger.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -658,6 +658,7 @@ static int prepare_connect_authorizer(st
+ void *auth_buf;
+ int auth_len;
+ int auth_protocol;
++ int ret;
+
+ if (!con->ops->get_authorizer) {
+ con->out_connect.authorizer_protocol = CEPH_AUTH_UNKNOWN;
+@@ -673,11 +674,14 @@ static int prepare_connect_authorizer(st
+ auth_buf = NULL;
+ auth_len = 0;
+ auth_protocol = CEPH_AUTH_UNKNOWN;
+- con->ops->get_authorizer(con, &auth_buf, &auth_len, &auth_protocol,
+- &con->auth_reply_buf, &con->auth_reply_buf_len,
+- con->auth_retry);
++ ret = con->ops->get_authorizer(con, &auth_buf, &auth_len,
++ &auth_protocol, &con->auth_reply_buf,
++ &con->auth_reply_buf_len, con->auth_retry);
+ mutex_lock(&con->mutex);
+
++ if (ret)
++ return ret;
++
+ if (test_bit(CLOSED, &con->state) || test_bit(OPENING, &con->state))
+ return -EAGAIN;
+
--- /dev/null
+From 264a7a0f668494ec2b1fed9c44e14e4b898628ef Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:38 -0500
+Subject: ceph: define ceph_auth_handshake type
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 6c4a19158b96ea1fb8acbe0c1d5493d9dcd2f147)
+
+The definitions for the ceph_mds_session and ceph_osd both contain
+five fields related only to "authorizers." Encapsulate those fields
+into their own struct type, allowing for better isolation in some
+upcoming patches.
+
+Fix the #includes in "linux/ceph/osd_client.h" to lay out their more
+complete canonical path.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/mds_client.c | 32 ++++++++++++++++----------------
+ fs/ceph/mds_client.h | 5 ++---
+ include/linux/ceph/auth.h | 8 ++++++++
+ include/linux/ceph/osd_client.h | 11 +++++------
+ net/ceph/osd_client.c | 32 ++++++++++++++++----------------
+ 5 files changed, 47 insertions(+), 41 deletions(-)
+
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -334,10 +334,10 @@ void ceph_put_mds_session(struct ceph_md
+ dout("mdsc put_session %p %d -> %d\n", s,
+ atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1);
+ if (atomic_dec_and_test(&s->s_ref)) {
+- if (s->s_authorizer)
++ if (s->s_auth.authorizer)
+ s->s_mdsc->fsc->client->monc.auth->ops->destroy_authorizer(
+ s->s_mdsc->fsc->client->monc.auth,
+- s->s_authorizer);
++ s->s_auth.authorizer);
+ kfree(s);
+ }
+ }
+@@ -3404,29 +3404,29 @@ static int get_authorizer(struct ceph_co
+ struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
+ int ret = 0;
+
+- if (force_new && s->s_authorizer) {
+- ac->ops->destroy_authorizer(ac, s->s_authorizer);
+- s->s_authorizer = NULL;
++ if (force_new && s->s_auth.authorizer) {
++ ac->ops->destroy_authorizer(ac, s->s_auth.authorizer);
++ s->s_auth.authorizer = NULL;
+ }
+- if (s->s_authorizer == NULL) {
++ if (s->s_auth.authorizer == NULL) {
+ if (ac->ops->create_authorizer) {
+ ret = ac->ops->create_authorizer(
+ ac, CEPH_ENTITY_TYPE_MDS,
+- &s->s_authorizer,
+- &s->s_authorizer_buf,
+- &s->s_authorizer_buf_len,
+- &s->s_authorizer_reply_buf,
+- &s->s_authorizer_reply_buf_len);
++ &s->s_auth.authorizer,
++ &s->s_auth.authorizer_buf,
++ &s->s_auth.authorizer_buf_len,
++ &s->s_auth.authorizer_reply_buf,
++ &s->s_auth.authorizer_reply_buf_len);
+ if (ret)
+ return ret;
+ }
+ }
+
+ *proto = ac->protocol;
+- *buf = s->s_authorizer_buf;
+- *len = s->s_authorizer_buf_len;
+- *reply_buf = s->s_authorizer_reply_buf;
+- *reply_len = s->s_authorizer_reply_buf_len;
++ *buf = s->s_auth.authorizer_buf;
++ *len = s->s_auth.authorizer_buf_len;
++ *reply_buf = s->s_auth.authorizer_reply_buf;
++ *reply_len = s->s_auth.authorizer_reply_buf_len;
+ return 0;
+ }
+
+@@ -3437,7 +3437,7 @@ static int verify_authorizer_reply(struc
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
+
+- return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len);
++ return ac->ops->verify_authorizer_reply(ac, s->s_auth.authorizer, len);
+ }
+
+ static int invalidate_authorizer(struct ceph_connection *con)
+--- a/fs/ceph/mds_client.h
++++ b/fs/ceph/mds_client.h
+@@ -11,6 +11,7 @@
+ #include <linux/ceph/types.h>
+ #include <linux/ceph/messenger.h>
+ #include <linux/ceph/mdsmap.h>
++#include <linux/ceph/auth.h>
+
+ /*
+ * Some lock dependencies:
+@@ -113,9 +114,7 @@ struct ceph_mds_session {
+
+ struct ceph_connection s_con;
+
+- struct ceph_authorizer *s_authorizer;
+- void *s_authorizer_buf, *s_authorizer_reply_buf;
+- size_t s_authorizer_buf_len, s_authorizer_reply_buf_len;
++ struct ceph_auth_handshake s_auth;
+
+ /* protected by s_gen_ttl_lock */
+ spinlock_t s_gen_ttl_lock;
+--- a/include/linux/ceph/auth.h
++++ b/include/linux/ceph/auth.h
+@@ -14,6 +14,14 @@
+ struct ceph_auth_client;
+ struct ceph_authorizer;
+
++struct ceph_auth_handshake {
++ struct ceph_authorizer *authorizer;
++ void *authorizer_buf;
++ size_t authorizer_buf_len;
++ void *authorizer_reply_buf;
++ size_t authorizer_reply_buf_len;
++};
++
+ struct ceph_auth_client_ops {
+ const char *name;
+
+--- a/include/linux/ceph/osd_client.h
++++ b/include/linux/ceph/osd_client.h
+@@ -6,9 +6,10 @@
+ #include <linux/mempool.h>
+ #include <linux/rbtree.h>
+
+-#include "types.h"
+-#include "osdmap.h"
+-#include "messenger.h"
++#include <linux/ceph/types.h>
++#include <linux/ceph/osdmap.h>
++#include <linux/ceph/messenger.h>
++#include <linux/ceph/auth.h>
+
+ /*
+ * Maximum object name size
+@@ -40,9 +41,7 @@ struct ceph_osd {
+ struct list_head o_requests;
+ struct list_head o_linger_requests;
+ struct list_head o_osd_lru;
+- struct ceph_authorizer *o_authorizer;
+- void *o_authorizer_buf, *o_authorizer_reply_buf;
+- size_t o_authorizer_buf_len, o_authorizer_reply_buf_len;
++ struct ceph_auth_handshake o_auth;
+ unsigned long lru_ttl;
+ int o_marked_for_keepalive;
+ struct list_head o_keepalive_item;
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -667,8 +667,8 @@ static void put_osd(struct ceph_osd *osd
+ if (atomic_dec_and_test(&osd->o_ref)) {
+ struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth;
+
+- if (osd->o_authorizer)
+- ac->ops->destroy_authorizer(ac, osd->o_authorizer);
++ if (osd->o_auth.authorizer)
++ ac->ops->destroy_authorizer(ac, osd->o_auth.authorizer);
+ kfree(osd);
+ }
+ }
+@@ -2117,27 +2117,27 @@ static int get_authorizer(struct ceph_co
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
+ int ret = 0;
+
+- if (force_new && o->o_authorizer) {
+- ac->ops->destroy_authorizer(ac, o->o_authorizer);
+- o->o_authorizer = NULL;
++ if (force_new && o->o_auth.authorizer) {
++ ac->ops->destroy_authorizer(ac, o->o_auth.authorizer);
++ o->o_auth.authorizer = NULL;
+ }
+- if (o->o_authorizer == NULL) {
++ if (o->o_auth.authorizer == NULL) {
+ ret = ac->ops->create_authorizer(
+ ac, CEPH_ENTITY_TYPE_OSD,
+- &o->o_authorizer,
+- &o->o_authorizer_buf,
+- &o->o_authorizer_buf_len,
+- &o->o_authorizer_reply_buf,
+- &o->o_authorizer_reply_buf_len);
++ &o->o_auth.authorizer,
++ &o->o_auth.authorizer_buf,
++ &o->o_auth.authorizer_buf_len,
++ &o->o_auth.authorizer_reply_buf,
++ &o->o_auth.authorizer_reply_buf_len);
+ if (ret)
+ return ret;
+ }
+
+ *proto = ac->protocol;
+- *buf = o->o_authorizer_buf;
+- *len = o->o_authorizer_buf_len;
+- *reply_buf = o->o_authorizer_reply_buf;
+- *reply_len = o->o_authorizer_reply_buf_len;
++ *buf = o->o_auth.authorizer_buf;
++ *len = o->o_auth.authorizer_buf_len;
++ *reply_buf = o->o_auth.authorizer_reply_buf;
++ *reply_len = o->o_auth.authorizer_reply_buf_len;
+ return 0;
+ }
+
+@@ -2148,7 +2148,7 @@ static int verify_authorizer_reply(struc
+ struct ceph_osd_client *osdc = o->o_osdc;
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+- return ac->ops->verify_authorizer_reply(ac, o->o_authorizer, len);
++ return ac->ops->verify_authorizer_reply(ac, o->o_auth.authorizer, len);
+ }
+
+ static int invalidate_authorizer(struct ceph_connection *con)
--- /dev/null
+From 1ded78d42d2d4fa895df865f43a1cdbd0a94f090 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@inktank.com>
+Date: Wed, 16 May 2012 15:16:39 -0500
+Subject: ceph: messenger: reduce args to create_authorizer
+
+From: Alex Elder <elder@inktank.com>
+
+(cherry picked from commit 74f1869f76d043bad12ec03b4d5f04a8c3d1f157)
+
+Make use of the new ceph_auth_handshake structure in order to reduce
+the number of arguments passed to the create_authorizor method in
+ceph_auth_client_ops. Use a local variable of that type as a
+shorthand in the get_authorizer method definitions.
+
+Signed-off-by: Alex Elder <elder@inktank.com>
+Reviewed-by: Sage Weil <sage@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/mds_client.c | 27 ++++++++++++---------------
+ include/linux/ceph/auth.h | 4 +---
+ net/ceph/auth_none.c | 15 +++++++--------
+ net/ceph/auth_x.c | 15 +++++++--------
+ net/ceph/osd_client.c | 26 +++++++++++---------------
+ 5 files changed, 38 insertions(+), 49 deletions(-)
+
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -3402,31 +3402,28 @@ static int get_authorizer(struct ceph_co
+ struct ceph_mds_session *s = con->private;
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
++ struct ceph_auth_handshake *auth = &s->s_auth;
+ int ret = 0;
+
+- if (force_new && s->s_auth.authorizer) {
+- ac->ops->destroy_authorizer(ac, s->s_auth.authorizer);
+- s->s_auth.authorizer = NULL;
++ if (force_new && auth->authorizer) {
++ ac->ops->destroy_authorizer(ac, auth->authorizer);
++ auth->authorizer = NULL;
+ }
+- if (s->s_auth.authorizer == NULL) {
++ if (auth->authorizer == NULL) {
+ if (ac->ops->create_authorizer) {
+- ret = ac->ops->create_authorizer(
+- ac, CEPH_ENTITY_TYPE_MDS,
+- &s->s_auth.authorizer,
+- &s->s_auth.authorizer_buf,
+- &s->s_auth.authorizer_buf_len,
+- &s->s_auth.authorizer_reply_buf,
+- &s->s_auth.authorizer_reply_buf_len);
++ ret = ac->ops->create_authorizer(ac,
++ CEPH_ENTITY_TYPE_MDS, auth);
+ if (ret)
+ return ret;
+ }
+ }
+
+ *proto = ac->protocol;
+- *buf = s->s_auth.authorizer_buf;
+- *len = s->s_auth.authorizer_buf_len;
+- *reply_buf = s->s_auth.authorizer_reply_buf;
+- *reply_len = s->s_auth.authorizer_reply_buf_len;
++ *buf = auth->authorizer_buf;
++ *len = auth->authorizer_buf_len;
++ *reply_buf = auth->authorizer_reply_buf;
++ *reply_len = auth->authorizer_reply_buf_len;
++
+ return 0;
+ }
+
+--- a/include/linux/ceph/auth.h
++++ b/include/linux/ceph/auth.h
+@@ -51,9 +51,7 @@ struct ceph_auth_client_ops {
+ * the response to authenticate the service.
+ */
+ int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type,
+- struct ceph_authorizer **a,
+- void **buf, size_t *len,
+- void **reply_buf, size_t *reply_len);
++ struct ceph_auth_handshake *auth);
+ int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a, size_t len);
+ void (*destroy_authorizer)(struct ceph_auth_client *ac,
+--- a/net/ceph/auth_none.c
++++ b/net/ceph/auth_none.c
+@@ -59,9 +59,7 @@ static int handle_reply(struct ceph_auth
+ */
+ static int ceph_auth_none_create_authorizer(
+ struct ceph_auth_client *ac, int peer_type,
+- struct ceph_authorizer **a,
+- void **buf, size_t *len,
+- void **reply_buf, size_t *reply_len)
++ struct ceph_auth_handshake *auth)
+ {
+ struct ceph_auth_none_info *ai = ac->private;
+ struct ceph_none_authorizer *au = &ai->au;
+@@ -82,11 +80,12 @@ static int ceph_auth_none_create_authori
+ dout("built authorizer len %d\n", au->buf_len);
+ }
+
+- *a = (struct ceph_authorizer *)au;
+- *buf = au->buf;
+- *len = au->buf_len;
+- *reply_buf = au->reply_buf;
+- *reply_len = sizeof(au->reply_buf);
++ auth->authorizer = (struct ceph_authorizer *) au;
++ auth->authorizer_buf = au->buf;
++ auth->authorizer_buf_len = au->buf_len;
++ auth->authorizer_reply_buf = au->reply_buf;
++ auth->authorizer_reply_buf_len = sizeof (au->reply_buf);
++
+ return 0;
+
+ bad2:
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -526,9 +526,7 @@ static int ceph_x_handle_reply(struct ce
+
+ static int ceph_x_create_authorizer(
+ struct ceph_auth_client *ac, int peer_type,
+- struct ceph_authorizer **a,
+- void **buf, size_t *len,
+- void **reply_buf, size_t *reply_len)
++ struct ceph_auth_handshake *auth)
+ {
+ struct ceph_x_authorizer *au;
+ struct ceph_x_ticket_handler *th;
+@@ -548,11 +546,12 @@ static int ceph_x_create_authorizer(
+ return ret;
+ }
+
+- *a = (struct ceph_authorizer *)au;
+- *buf = au->buf->vec.iov_base;
+- *len = au->buf->vec.iov_len;
+- *reply_buf = au->reply_buf;
+- *reply_len = sizeof(au->reply_buf);
++ auth->authorizer = (struct ceph_authorizer *) au;
++ auth->authorizer_buf = au->buf->vec.iov_base;
++ auth->authorizer_buf_len = au->buf->vec.iov_len;
++ auth->authorizer_reply_buf = au->reply_buf;
++ auth->authorizer_reply_buf_len = sizeof (au->reply_buf);
++
+ return 0;
+ }
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -2115,29 +2115,25 @@ static int get_authorizer(struct ceph_co
+ struct ceph_osd *o = con->private;
+ struct ceph_osd_client *osdc = o->o_osdc;
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
++ struct ceph_auth_handshake *auth = &o->o_auth;
+ int ret = 0;
+
+- if (force_new && o->o_auth.authorizer) {
+- ac->ops->destroy_authorizer(ac, o->o_auth.authorizer);
+- o->o_auth.authorizer = NULL;
++ if (force_new && auth->authorizer) {
++ ac->ops->destroy_authorizer(ac, auth->authorizer);
++ auth->authorizer = NULL;
+ }
+- if (o->o_auth.authorizer == NULL) {
+- ret = ac->ops->create_authorizer(
+- ac, CEPH_ENTITY_TYPE_OSD,
+- &o->o_auth.authorizer,
+- &o->o_auth.authorizer_buf,
+- &o->o_auth.authorizer_buf_len,
+- &o->o_auth.authorizer_reply_buf,
+- &o->o_auth.authorizer_reply_buf_len);
++ if (auth->authorizer == NULL) {
++ ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_OSD, auth);
+ if (ret)
+ return ret;
+ }
+
+ *proto = ac->protocol;
+- *buf = o->o_auth.authorizer_buf;
+- *len = o->o_auth.authorizer_buf_len;
+- *reply_buf = o->o_auth.authorizer_reply_buf;
+- *reply_len = o->o_auth.authorizer_reply_buf_len;
++ *buf = auth->authorizer_buf;
++ *len = auth->authorizer_buf_len;
++ *reply_buf = auth->authorizer_reply_buf;
++ *reply_len = auth->authorizer_reply_buf_len;
++
+ return 0;
+ }
+
0006-ceph-osd_client-fix-endianness-bug-in-osd_req_encode.patch
0007-ceph-messenger-use-read_partial-in-read_partial_mess.patch
0008-ceph-messenger-update-to-in-read_partial-caller.patch
+0009-ceph-messenger-change-read_partial-to-take-end-arg.patch
+0010-libceph-don-t-reset-kvec-in-prepare_write_banner.patch
+0011-ceph-messenger-reset-connection-kvec-caller.patch
+0012-ceph-messenger-send-banner-in-process_connect.patch
+0013-ceph-drop-msgr-argument-from-prepare_write_connect.patch
+0014-ceph-don-t-set-WRITE_PENDING-too-early.patch
+0015-ceph-messenger-check-prepare_write_connect-result.patch
+0016-ceph-messenger-rework-prepare_connect_authorizer.patch
+0017-ceph-messenger-check-return-from-get_authorizer.patch
+0018-ceph-define-ceph_auth_handshake-type.patch
+0019-ceph-messenger-reduce-args-to-create_authorizer.patch