summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-12-05 07:24:17 +0000
committermav <mav@FreeBSD.org>2014-12-05 07:24:17 +0000
commit0d78a1c549aca0c9e0ee3f559772568404b3f985 (patch)
tree4f04f3bca3c909bfe403e25f15845ced1f9c83b9 /sys/cam
parentcc2f0f4af54e23d5cd1b038f9967f372ff24d709 (diff)
downloadFreeBSD-src-0d78a1c549aca0c9e0ee3f559772568404b3f985.zip
FreeBSD-src-0d78a1c549aca0c9e0ee3f559772568404b3f985.tar.gz
MFC r274795:
Close race between cfiscsi_offline() and new connection arrival. Incoming connection should be either rejected or accepted and terminated.
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ctl/ctl_frontend_iscsi.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c
index ef944e2..6308825 100644
--- a/sys/cam/ctl/ctl_frontend_iscsi.c
+++ b/sys/cam/ctl/ctl_frontend_iscsi.c
@@ -1064,6 +1064,8 @@ cfiscsi_session_terminate_tasks(struct cfiscsi_session *cs)
union ctl_io *io;
int error, last, wait;
+ if (cs->cs_target == NULL)
+ return; /* No target yet, so nothing to do. */
io = ctl_alloc_io(cs->cs_target->ct_port.ctl_pool_ref);
if (io == NULL) {
CFISCSI_SESSION_WARN(cs, "can't allocate ctl_io");
@@ -1247,11 +1249,7 @@ cfiscsi_session_new(struct cfiscsi_softc *softc)
}
mtx_lock(&softc->lock);
- cs->cs_id = softc->last_session_id + 1;
- softc->last_session_id++;
- mtx_unlock(&softc->lock);
-
- mtx_lock(&softc->lock);
+ cs->cs_id = ++softc->last_session_id;
TAILQ_INSERT_TAIL(&softc->sessions, cs, cs_next);
mtx_unlock(&softc->lock);
@@ -1429,14 +1427,6 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
return;
}
- if (ct->ct_online == 0) {
- ci->status = CTL_ISCSI_ERROR;
- snprintf(ci->error_str, sizeof(ci->error_str),
- "%s: port offline", __func__);
- cfiscsi_target_release(ct);
- return;
- }
-
#ifdef ICL_KERNEL_PROXY
if (cihp->socket > 0 && cihp->connection_id > 0) {
snprintf(ci->error_str, sizeof(ci->error_str),
@@ -1448,7 +1438,7 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
if (cihp->socket == 0) {
mtx_lock(&cfiscsi_softc.lock);
TAILQ_FOREACH(cs, &cfiscsi_softc.sessions, cs_next) {
- if (cs->cs_id == cihp->socket)
+ if (cs->cs_id == cihp->connection_id)
break;
}
if (cs == NULL) {
@@ -1473,7 +1463,6 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
#ifdef ICL_KERNEL_PROXY
}
#endif
- cs->cs_target = ct;
/*
* First PDU of Full Feature phase has the same CmdSN as the last
@@ -1505,6 +1494,19 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
cihp->initiator_isid[2], cihp->initiator_isid[3],
cihp->initiator_isid[4], cihp->initiator_isid[5]);
+ mtx_lock(&softc->lock);
+ if (ct->ct_online == 0) {
+ mtx_unlock(&softc->lock);
+ cfiscsi_session_terminate(cs);
+ cfiscsi_target_release(ct);
+ ci->status = CTL_ISCSI_ERROR;
+ snprintf(ci->error_str, sizeof(ci->error_str),
+ "%s: port offline", __func__);
+ return;
+ }
+ cs->cs_target = ct;
+ mtx_unlock(&softc->lock);
+
refcount_acquire(&cs->cs_outstanding_ctl_pdus);
restart:
if (!cs->cs_terminating) {
OpenPOWER on IntegriCloud