diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2020-11-06 17:07:07 +0100 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2020-12-14 23:21:48 +0100 |
commit | 3596f4c1241d3c9b6a7cb03b7209c1897c3a5390 (patch) | |
tree | 57126074089c8729c05169a68827461b2f6bcd55 /net/ceph/messenger.c | |
parent | libceph: don't call reset_connection() on version/feature mismatches (diff) | |
download | linux-3596f4c1241d3c9b6a7cb03b7209c1897c3a5390.tar.xz linux-3596f4c1241d3c9b6a7cb03b7209c1897c3a5390.zip |
libceph: split protocol reset bits out of reset_connection()
Move protocol reset bits into ceph_con_reset_protocol(), leaving
just session reset bits.
Note that con->out_skip is now reset on faults. This fixes a crash
in the case of a stateful session getting a fault while in the middle
of revoking a message.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to '')
-rw-r--r-- | net/ceph/messenger.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index a73525de7b70..37166f130d44 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -613,6 +613,25 @@ static int con_close_socket(struct ceph_connection *con) return rc; } +static void ceph_con_reset_protocol(struct ceph_connection *con) +{ + dout("%s con %p\n", __func__, con); + + con_close_socket(con); + if (con->in_msg) { + WARN_ON(con->in_msg->con != con); + ceph_msg_put(con->in_msg); + con->in_msg = NULL; + } + if (con->out_msg) { + WARN_ON(con->out_msg->con != con); + ceph_msg_put(con->out_msg); + con->out_msg = NULL; + } + + con->out_skip = 0; +} + /* * Reset a connection. Discard all incoming and outgoing messages * and clear *_seq state. @@ -637,26 +656,16 @@ static void reset_connection(struct ceph_connection *con) /* reset connection, out_queue, msg_ and connect_seq */ /* discard existing out_queue and msg_seq */ dout("reset_connection %p\n", con); + + WARN_ON(con->in_msg); + WARN_ON(con->out_msg); ceph_msg_remove_list(&con->out_queue); ceph_msg_remove_list(&con->out_sent); - if (con->in_msg) { - BUG_ON(con->in_msg->con != con); - ceph_msg_put(con->in_msg); - con->in_msg = NULL; - } - con->connect_seq = 0; con->out_seq = 0; - if (con->out_msg) { - BUG_ON(con->out_msg->con != con); - ceph_msg_put(con->out_msg); - con->out_msg = NULL; - } con->in_seq = 0; con->in_seq_acked = 0; - - con->out_skip = 0; } /* @@ -673,10 +682,10 @@ void ceph_con_close(struct ceph_connection *con) con_flag_clear(con, CON_FLAG_WRITE_PENDING); con_flag_clear(con, CON_FLAG_BACKOFF); + ceph_con_reset_protocol(con); reset_connection(con); con->peer_global_seq = 0; cancel_con(con); - con_close_socket(con); mutex_unlock(&con->mutex); } EXPORT_SYMBOL(ceph_con_close); @@ -2986,7 +2995,7 @@ static void con_fault(struct ceph_connection *con) con->state != CON_STATE_NEGOTIATING && con->state != CON_STATE_OPEN); - con_close_socket(con); + ceph_con_reset_protocol(con); if (con_flag_test(con, CON_FLAG_LOSSYTX)) { dout("fault on LOSSYTX channel, marking CLOSED\n"); @@ -2994,17 +3003,6 @@ static void con_fault(struct ceph_connection *con) return; } - if (con->in_msg) { - BUG_ON(con->in_msg->con != con); - ceph_msg_put(con->in_msg); - con->in_msg = NULL; - } - if (con->out_msg) { - BUG_ON(con->out_msg->con != con); - ceph_msg_put(con->out_msg); - con->out_msg = NULL; - } - /* Requeue anything that hasn't been acked */ list_splice_init(&con->out_sent, &con->out_queue); |