diff options
Diffstat (limited to 'sys/cam/ctl/ctl_frontend_iscsi.c')
-rw-r--r-- | sys/cam/ctl/ctl_frontend_iscsi.c | 56 |
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); |