aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/ctl/ctl_frontend_iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam/ctl/ctl_frontend_iscsi.c')
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c56
1 files changed, 30 insertions, 26 deletions
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index 6b002566b465..fe3b1a943206 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2012 The FreeBSD Foundation
*
@@ -26,17 +26,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
/*
* CTL frontend for the iSCSI protocol.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/param.h>
#include <sys/capsicum.h>
#include <sys/condvar.h>
@@ -84,6 +79,9 @@ __FBSDID("$FreeBSD$");
FEATURE(cfiscsi_kernel_proxy, "iSCSI target built with ICL_KERNEL_PROXY");
#endif
+/* Used for internal nexus reset task. */
+#define ISCSI_BHS_OPCODE_INTERNAL 0x3e
+
static MALLOC_DEFINE(M_CFISCSI, "cfiscsi", "Memory used for CTL iSCSI frontend");
static uma_zone_t cfiscsi_data_wait_zone;
@@ -1083,8 +1081,8 @@ cfiscsi_data_wait_new(struct cfiscsi_session *cs, union ctl_io *io,
return (NULL);
}
- error = icl_conn_transfer_setup(cs->cs_conn, io, target_transfer_tagp,
- &cdw->cdw_icl_prv);
+ error = icl_conn_transfer_setup(cs->cs_conn, PRIV_REQUEST(io), io,
+ target_transfer_tagp, &cdw->cdw_icl_prv);
if (error != 0) {
CFISCSI_SESSION_WARN(cs,
"icl_conn_transfer_setup() failed with error %d", error);
@@ -1131,14 +1129,17 @@ static void
cfiscsi_session_terminate_tasks(struct cfiscsi_session *cs)
{
struct cfiscsi_data_wait *cdw;
+ struct icl_pdu *ip;
union ctl_io *io;
int error, last, wait;
if (cs->cs_target == NULL)
return; /* No target yet, so nothing to do. */
+ ip = icl_pdu_new(cs->cs_conn, M_WAITOK);
+ ip->ip_bhs->bhs_opcode = ISCSI_BHS_OPCODE_INTERNAL;
io = ctl_alloc_io(cs->cs_target->ct_port.ctl_pool_ref);
ctl_zero_io(io);
- PRIV_REQUEST(io) = cs;
+ PRIV_REQUEST(io) = ip;
io->io_hdr.io_type = CTL_IO_TASK;
io->io_hdr.nexus.initid = cs->cs_ctl_initid;
io->io_hdr.nexus.targ_port = cs->cs_target->ct_port.targ_port;
@@ -1152,9 +1153,11 @@ cfiscsi_session_terminate_tasks(struct cfiscsi_session *cs)
CFISCSI_SESSION_WARN(cs, "ctl_run() failed; error %d", error);
refcount_release(&cs->cs_outstanding_ctl_pdus);
ctl_free_io(io);
+ icl_pdu_free(ip);
}
CFISCSI_SESSION_LOCK(cs);
+ cs->cs_terminating_tasks = true;
while ((cdw = TAILQ_FIRST(&cs->cs_waiting_for_data_out)) != NULL) {
TAILQ_REMOVE(&cs->cs_waiting_for_data_out, cdw, cdw_next);
CFISCSI_SESSION_UNLOCK(cs);
@@ -1718,7 +1721,7 @@ cfiscsi_ioctl_list(struct ctl_iscsi *ci)
return;
}
- sbuf_printf(sb, "<ctlislist>\n");
+ sbuf_cat(sb, "<ctlislist>\n");
mtx_lock(&softc->lock);
TAILQ_FOREACH(cs, &softc->sessions, cs_next) {
if (cs->cs_target == NULL)
@@ -1757,7 +1760,7 @@ cfiscsi_ioctl_list(struct ctl_iscsi *ci)
break;
}
mtx_unlock(&softc->lock);
- error = sbuf_printf(sb, "</ctlislist>\n");
+ error = sbuf_cat(sb, "</ctlislist>\n");
if (error != 0) {
sbuf_delete(sb);
ci->status = CTL_ISCSI_LIST_NEED_MORE_SPACE;
@@ -1888,7 +1891,7 @@ cfiscsi_ioctl_limits(struct ctl_iscsi *ci)
cilp = (struct ctl_iscsi_limits_params *)&(ci->data);
- error = icl_limits(cilp->offload, false, &idl);
+ error = icl_limits(cilp->offload, false, cilp->socket, &idl);
if (error != 0) {
ci->status = CTL_ISCSI_ERROR;
snprintf(ci->error_str, sizeof(ci->error_str),
@@ -2783,8 +2786,12 @@ cfiscsi_datamove_out(union ctl_io *io)
cdw->cdw_r2t_end = io->scsiio.ext_data_filled + r2t_len;
CFISCSI_SESSION_LOCK(cs);
- if (cs->cs_terminating) {
+ if (cs->cs_terminating_tasks) {
CFISCSI_SESSION_UNLOCK(cs);
+ KASSERT((io->io_hdr.flags & CTL_FLAG_ABORT) != 0,
+ ("%s: I/O request %p on termating session %p not aborted",
+ __func__, io, cs));
+ CFISCSI_SESSION_WARN(cs, "aborting data_wait for aborted I/O");
cfiscsi_data_wait_abort(cs, cdw, 44);
return;
}
@@ -3036,19 +3043,6 @@ cfiscsi_done(union ctl_io *io)
KASSERT(((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE),
("invalid CTL status %#x", io->io_hdr.status));
- if (io->io_hdr.io_type == CTL_IO_TASK &&
- io->taskio.task_action == CTL_TASK_I_T_NEXUS_RESET) {
- /*
- * Implicit task termination has just completed; nothing to do.
- */
- cs = PRIV_REQUEST(io);
- cs->cs_tasks_aborted = true;
- refcount_release(&cs->cs_outstanding_ctl_pdus);
- wakeup(__DEVOLATILE(void *, &cs->cs_outstanding_ctl_pdus));
- ctl_free_io(io);
- return;
- }
-
request = PRIV_REQUEST(io);
cs = PDU_SESSION(request);
@@ -3059,6 +3053,16 @@ cfiscsi_done(union ctl_io *io)
case ISCSI_BHS_OPCODE_TASK_REQUEST:
cfiscsi_task_management_done(io);
break;
+ case ISCSI_BHS_OPCODE_INTERNAL:
+ /*
+ * Implicit task termination has just completed; nothing to do.
+ */
+ icl_pdu_free(request);
+ cs->cs_tasks_aborted = true;
+ refcount_release(&cs->cs_outstanding_ctl_pdus);
+ wakeup(__DEVOLATILE(void *, &cs->cs_outstanding_ctl_pdus));
+ ctl_free_io(io);
+ return;
default:
panic("cfiscsi_done called with wrong opcode 0x%x",
request->ip_bhs->bhs_opcode);