summaryrefslogtreecommitdiff
path: root/sys/dev/iscsi
diff options
context:
space:
mode:
authormlelstv <mlelstv@NetBSD.org>2016-06-05 13:54:28 +0000
committermlelstv <mlelstv@NetBSD.org>2016-06-05 13:54:28 +0000
commit6c96695f08b4db22c8f14915ab7571aaee694e12 (patch)
tree06bdf5ea9cb6ff21f26842d511d84f1750947c4a /sys/dev/iscsi
parent371f1730f4b5d2fd72ab5dae5df32b48aaa2068b (diff)
Handle freeing of PDU when referencing CCB is freed.
Diffstat (limited to 'sys/dev/iscsi')
-rw-r--r--sys/dev/iscsi/iscsi_send.c12
-rw-r--r--sys/dev/iscsi/iscsi_utils.c15
2 files changed, 19 insertions, 8 deletions
diff --git a/sys/dev/iscsi/iscsi_send.c b/sys/dev/iscsi/iscsi_send.c
index 6269f546b3c..d6f49731843 100644
--- a/sys/dev/iscsi/iscsi_send.c
+++ b/sys/dev/iscsi/iscsi_send.c
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_send.c,v 1.29 2016/06/05 09:12:48 mlelstv Exp $ */
+/* $NetBSD: iscsi_send.c,v 1.30 2016/06/05 13:54:28 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -291,6 +291,7 @@ iscsi_send_thread(void *par)
ccb_t *ccb, *nccb;
pdu_t *pdu;
struct file *fp;
+ pdu_disp_t pdisp;
sess = conn->session;
/* so cleanup thread knows there's someone left */
@@ -302,6 +303,7 @@ iscsi_send_thread(void *par)
while (!conn->terminating &&
(pdu = TAILQ_FIRST(&conn->pdus_to_send)) != NULL) {
TAILQ_REMOVE(&conn->pdus_to_send, pdu, send_chain);
+ pdu->flags &= ~PDUF_INQUEUE;
mutex_exit(&conn->lock);
/* update ExpStatSN here to avoid discontinuities */
@@ -315,12 +317,14 @@ iscsi_send_thread(void *par)
my_soo_write(conn, &pdu->uio);
mutex_enter(&conn->lock);
- pdu->flags &= ~PDUF_INQUEUE;
- if (pdu->disp > PDUDISP_FREE)
+ pdisp = pdu->disp;
+ if (pdisp <= PDUDISP_FREE)
+ pdu->disp = PDUDISP_UNUSED;
+ else
pdu->flags &= ~PDUF_BUSY;
mutex_exit(&conn->lock);
- if (pdu->disp <= PDUDISP_FREE)
+ if (pdisp <= PDUDISP_FREE)
free_pdu(pdu);
mutex_enter(&conn->lock);
diff --git a/sys/dev/iscsi/iscsi_utils.c b/sys/dev/iscsi/iscsi_utils.c
index 7444159e7a7..0286903903b 100644
--- a/sys/dev/iscsi/iscsi_utils.c
+++ b/sys/dev/iscsi/iscsi_utils.c
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_utils.c,v 1.18 2016/06/05 09:21:14 mlelstv Exp $ */
+/* $NetBSD: iscsi_utils.c,v 1.19 2016/06/05 13:54:28 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2008 The NetBSD Foundation, Inc.
@@ -268,16 +268,17 @@ void
free_ccb(ccb_t *ccb)
{
session_t *sess = ccb->session;
+ connection_t *conn = ccb->connection;
pdu_t *pdu;
- DEBC(ccb->connection, 15, (
+ DEBC(conn, 15, (
"free_ccb: ccb = %p, usecount = %d\n",
- ccb, ccb->connection->usecount-1));
+ ccb, conn->usecount-1));
KASSERT((ccb->flags & CCBF_THROTTLING) == 0);
KASSERT((ccb->flags & CCBF_WAITQUEUE) == 0);
- atomic_dec_uint(&ccb->connection->usecount);
+ atomic_dec_uint(&conn->usecount);
ccb->connection = NULL;
if (ccb->disp > CCBDISP_NOWAIT) {
@@ -296,6 +297,12 @@ free_ccb(ccb_t *ccb)
/* free PDU waiting for ACK */
if ((pdu = ccb->pdu_waiting) != NULL) {
ccb->pdu_waiting = NULL;
+ mutex_enter(&conn->lock);
+ if ((pdu->flags & PDUF_INQUEUE) != 0) {
+ TAILQ_REMOVE(&conn->pdus_to_send, pdu, send_chain);
+ pdu->flags &= ~PDUF_INQUEUE;
+ }
+ mutex_exit(&conn->lock);
free_pdu(pdu);
}