From: Martin Belanger Move the read loop out of nvme_tcp_skip_tls_record() into a new helper, nvme_tcp_drain_tls_record(). The next patch uses the helper to read TLS records that arrive on a live queue. No functional change. Cc: stable@vger.kernel.org Signed-off-by: Martin Belanger Reviewed-by: Hannes Reinecke --- drivers/nvme/host/tcp.c | 60 +++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 749d77b4e172..c3bf345c4e92 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1629,31 +1629,16 @@ static int nvme_tcp_recv_tls_alert(struct nvme_tcp_queue *queue, } /* - * Discard a TLS record that arrived in place of the ICResp. A peer may send - * a NewSessionTicket as soon as the handshake completes. + * Read the rest of a TLS record whose first part was read into @msg. * - * Returns 0 when the record was discarded and the ICResp can be read, or a - * negative errno if the connection cannot continue. + * Returns the bytes read, or a negative errno. */ -static int nvme_tcp_skip_tls_record(struct nvme_tcp_queue *queue, - struct msghdr *msg, u8 ctype, int len) +static int nvme_tcp_drain_tls_record(struct nvme_tcp_queue *queue, + struct msghdr *msg, int flags) { u8 buf[NVME_TCP_TLS_REC_CHUNK]; - int ret; + int ret, drained = 0; - switch (ctype) { - case TLS_RECORD_TYPE_HANDSHAKE: - break; - case TLS_RECORD_TYPE_ALERT: - ret = nvme_tcp_recv_tls_alert(queue, msg, len); - return ret ? : -ENOTCONN; - default: - pr_err("queue %d: unhandled TLS record %u\n", - nvme_tcp_queue_id(queue), ctype); - return -ENOTCONN; - } - - /* the ICResp is in a later record, drain this one first */ while (!(msg->msg_flags & MSG_EOR)) { struct kvec iov = { .iov_base = buf, @@ -1667,16 +1652,47 @@ static int nvme_tcp_skip_tls_record(struct nvme_tcp_queue *queue, }; ret = kernel_recvmsg(queue->sock, &drain, &iov, 1, sizeof(buf), - 0); + flags); if (ret <= 0) { pr_warn("queue %d: failed to drain TLS record: %d\n", nvme_tcp_queue_id(queue), ret); return ret ? : -ECONNRESET; } + drained += ret; msg->msg_flags = drain.msg_flags; } - return 0; + return drained; +} + +/* + * Discard a TLS record that arrived in place of the ICResp. A peer may send + * a NewSessionTicket as soon as the handshake completes. + * + * Returns 0 when the record was discarded and the ICResp can be read, or a + * negative errno if the connection cannot continue. + */ +static int nvme_tcp_skip_tls_record(struct nvme_tcp_queue *queue, + struct msghdr *msg, u8 ctype, int len) +{ + int ret; + + switch (ctype) { + case TLS_RECORD_TYPE_HANDSHAKE: + break; + case TLS_RECORD_TYPE_ALERT: + ret = nvme_tcp_recv_tls_alert(queue, msg, len); + return ret ? : -ENOTCONN; + default: + pr_err("queue %d: unhandled TLS record %u\n", + nvme_tcp_queue_id(queue), ctype); + return -ENOTCONN; + } + + /* the ICResp is in a later record, drain this one first */ + ret = nvme_tcp_drain_tls_record(queue, msg, 0); + + return ret < 0 ? ret : 0; } /* -- 2.53.0