summaryrefslogtreecommitdiff
path: root/drivers/nvme/target/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvme/target/tcp.c')
-rw-r--r--drivers/nvme/target/tcp.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 15416ff0eac4..549a4786d1c3 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -982,6 +982,18 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len);
goto err_proto;
}
+ /*
+ * Ensure command data structures are initialized. We must check both
+ * cmd->req.sg and cmd->iov because they can have different NULL states:
+ * - Uninitialized commands: both NULL
+ * - READ commands: cmd->req.sg allocated, cmd->iov NULL
+ * - WRITE commands: both allocated
+ */
+ if (unlikely(!cmd->req.sg || !cmd->iov)) {
+ pr_err("queue %d: H2CData PDU received for invalid command state (ttag %u)\n",
+ queue->idx, data->ttag);
+ goto err_proto;
+ }
cmd->pdu_recv = 0;
nvmet_tcp_build_pdu_iovec(cmd);
queue->cmd = cmd;
@@ -1992,14 +2004,13 @@ static void nvmet_tcp_listen_data_ready(struct sock *sk)
trace_sk_data_ready(sk);
+ if (sk->sk_state != TCP_LISTEN)
+ return;
+
read_lock_bh(&sk->sk_callback_lock);
port = sk->sk_user_data;
- if (!port)
- goto out;
-
- if (sk->sk_state == TCP_LISTEN)
+ if (port)
queue_work(nvmet_wq, &port->accept_work);
-out:
read_unlock_bh(&sk->sk_callback_lock);
}