* iscsi fixes and features for 2.6.33 @ 2009-11-11 22:34 michaelc 2009-11-11 22:34 ` [PATCH 1/7] bnx2i: use common iscsi suspend queue michaelc 0 siblings, 1 reply; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi The following patches are for 2.6.33. They were made over scsi-misc. [PATCH 1/7] bnx2i: use common iscsi suspend queue [PATCH 2/7] libiscsi: fix login/text checks in pdu injection code [PATCH 3/7] libiscsi: Check TMF state before sending PDU [PATCH 4/7] libiscsi: add warm target reset tmf support [PATCH 5/7] iscsi class: modify handling of replacement timeout [PATCH 6/7] iser: set tgt and lu reset timeout [PATCH 7/7] libiscsi: hook into ramp up/down handling ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/7] bnx2i: use common iscsi suspend queue 2009-11-11 22:34 iscsi fixes and features for 2.6.33 michaelc @ 2009-11-11 22:34 ` michaelc 2009-11-11 22:34 ` [PATCH 2/7] libiscsi: fix login/text checks in pdu injection code michaelc 2009-11-12 2:00 ` [PATCH 1/7] bnx2i: use common iscsi suspend queue Anil Veerabhadrappa 0 siblings, 2 replies; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi; +Cc: Mike Christie From: Mike Christie <michaelc@cs.wisc.edu> This just has bnx2i use the iscsi_suspend_queue helper. The suspend works as follows: When ep_poll has succeeed iscsid will call conn_bind, the LLD will then call iscsi_conn_bind which will clear the suspend bit. When ep_disconnect is called (or if there is a conn error) we set the suspend bit. For the ep_disconnect case I added a helper in the previous kernel that will take the session lock to make sure iscsi_queuecommand/xmit_task is not running and it will set the suspend bit. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> --- drivers/scsi/bnx2i/bnx2i.h | 1 - drivers/scsi/bnx2i/bnx2i_iscsi.c | 8 +------- 2 files changed, 1 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 5edde1a..2b973f3 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -232,7 +232,6 @@ struct bnx2i_conn { struct iscsi_cls_conn *cls_conn; struct bnx2i_hba *hba; struct completion cmd_cleanup_cmpl; - int is_bound; u32 iscsi_conn_cid; #define BNX2I_CID_RESERVED 0x5AFF diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index cafb888..89e84c3 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -1161,9 +1161,6 @@ static int bnx2i_task_xmit(struct iscsi_task *task) struct bnx2i_cmd *cmd = task->dd_data; struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; - if (!bnx2i_conn->is_bound) - return -ENOTCONN; - /* * If there is no scsi_cmnd this must be a mgmt task */ @@ -1371,7 +1368,6 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session, bnx2i_conn->ep = bnx2i_ep; bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid; bnx2i_conn->fw_cid = bnx2i_ep->ep_cid; - bnx2i_conn->is_bound = 1; ret_code = bnx2i_bind_conn_to_iscsi_cid(hba, bnx2i_conn, bnx2i_ep->ep_iscsi_cid); @@ -1896,9 +1892,7 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep) conn = bnx2i_conn->cls_conn->dd_data; session = conn->session; - spin_lock_bh(&session->lock); - bnx2i_conn->is_bound = 0; - spin_unlock_bh(&session->lock); + iscsi_suspend_queue(conn); } hba = bnx2i_ep->hba; -- 1.6.2.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/7] libiscsi: fix login/text checks in pdu injection code 2009-11-11 22:34 ` [PATCH 1/7] bnx2i: use common iscsi suspend queue michaelc @ 2009-11-11 22:34 ` michaelc 2009-11-11 22:34 ` [PATCH 3/7] libiscsi: Check TMF state before sending PDU michaelc 2009-11-12 2:00 ` [PATCH 1/7] bnx2i: use common iscsi suspend queue Anil Veerabhadrappa 1 sibling, 1 reply; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi; +Cc: Mike Christie From: Mike Christie <michaelc@cs.wisc.edu> For some reason we used to check for the the immediate bit set and the opcocde in many places instead of just masking the opcode. In the passthrough code this is a problem because userspace may or may not have set the immediate bit and it does not have to. This fixes up the opcode checks in the passthrough code, so we mask off the opcode then check against the iscsi proto definition like is done in other places. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> --- drivers/scsi/libiscsi.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 67d0f3f..8c29480 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -577,12 +577,12 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, struct iscsi_session *session = conn->session; struct iscsi_hdr *hdr = task->hdr; struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; + uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK; if (conn->session->state == ISCSI_STATE_LOGGING_OUT) return -ENOTCONN; - if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) && - hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) + if (opcode != ISCSI_OP_LOGIN && opcode != ISCSI_OP_TEXT) nop->exp_statsn = cpu_to_be32(conn->exp_statsn); /* * pre-format CmdSN for outgoing PDU. @@ -590,9 +590,12 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, nop->cmdsn = cpu_to_be32(session->cmdsn); if (hdr->itt != RESERVED_ITT) { /* - * TODO: We always use immediate, so we never hit this. + * TODO: We always use immediate for normal session pdus. * If we start to send tmfs or nops as non-immediate then * we should start checking the cmdsn numbers for mgmt tasks. + * + * During discovery sessions iscsid sends TEXT as non immediate, + * but we always only send one PDU at a time. */ if (conn->c_stage == ISCSI_CONN_STARTED && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { @@ -620,22 +623,28 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, { struct iscsi_session *session = conn->session; struct iscsi_host *ihost = shost_priv(session->host); + uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK; struct iscsi_task *task; itt_t itt; if (session->state == ISCSI_STATE_TERMINATE) return NULL; - if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || - hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) + if (opcode == ISCSI_OP_LOGIN || opcode == ISCSI_OP_TEXT) { /* * Login and Text are sent serially, in * request-followed-by-response sequence. * Same task can be used. Same ITT must be used. * Note that login_task is preallocated at conn_create(). */ + if (conn->login_task->state != ISCSI_TASK_FREE) { + iscsi_conn_printk(KERN_ERR, conn, "Login/Text in " + "progress. Cannot start new task.\n"); + return NULL; + } + task = conn->login_task; - else { + } else { if (session->state != ISCSI_STATE_LOGGED_IN) return NULL; -- 1.6.2.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7] libiscsi: Check TMF state before sending PDU 2009-11-11 22:34 ` [PATCH 2/7] libiscsi: fix login/text checks in pdu injection code michaelc @ 2009-11-11 22:34 ` michaelc 2009-11-11 22:34 ` [PATCH 4/7] libiscsi: add warm target reset tmf support michaelc 0 siblings, 1 reply; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi; +Cc: Mike Christie, Hannes Reinecke From: Mike Christie <michaelc@cs.wisc.edu> Patch and mail from both MikeC and HannesR: Before we're trying to send a PDU we have to check whether a TMF is active. If so and if the PDU will be affected by the TMF we should allow only Data-out PDUs to be sent. If fast_abort is set, no Data-out PDUs will be sent while a LUN reset is being processed for a affected LUN. fast_abort is now ingored during a ABORT TASK tmf. We will not send any Data-outs for a task if the task is being aborted. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: Hannes Reinecke <hare@suse.de> --- drivers/scsi/libiscsi.c | 113 +++++++++++++++++++++++++++++++++++++++----- include/scsi/iscsi_proto.h | 2 + 2 files changed, 103 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 8c29480..b6ffdc5 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -266,6 +266,88 @@ static int iscsi_prep_bidi_ahs(struct iscsi_task *task) } /** + * iscsi_check_tmf_restrictions - check if a task is affected by TMF + * @task: iscsi task + * @opcode: opcode to check for + * + * During TMF a task has to be checked if it's affected. + * All unrelated I/O can be passed through, but I/O to the + * affected LUN should be restricted. + * If 'fast_abort' is set we won't be sending any I/O to the + * affected LUN. + * Otherwise the target is waiting for all TTTs to be completed, + * so we have to send all outstanding Data-Out PDUs to the target. + */ +static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode) +{ + struct iscsi_conn *conn = task->conn; + struct iscsi_tm *tmf = &conn->tmhdr; + unsigned int hdr_lun; + + if (conn->tmf_state == TMF_INITIAL) + return 0; + + if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC) + return 0; + + switch (ISCSI_TM_FUNC_VALUE(tmf)) { + case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET: + /* + * Allow PDUs for unrelated LUNs + */ + hdr_lun = scsilun_to_int((struct scsi_lun *)tmf->lun); + if (hdr_lun != task->sc->device->lun) + return 0; + + /* + * Fail all SCSI cmd PDUs + */ + if (opcode != ISCSI_OP_SCSI_DATA_OUT) { + iscsi_conn_printk(KERN_INFO, conn, + "task [op %x/%x itt " + "0x%x/0x%x lun %u] " + "rejected.\n", + task->hdr->opcode, opcode, + task->itt, task->hdr_itt, hdr_lun); + return -EACCES; + } + /* + * And also all data-out PDUs in response to R2T + * if fast_abort is set. + */ + if (conn->session->fast_abort) { + iscsi_conn_printk(KERN_INFO, conn, + "task [op %x/%x itt " + "0x%x/0x%x lun %u] " + "fast abort.\n", + task->hdr->opcode, opcode, + task->itt, task->hdr_itt, hdr_lun); + return -EACCES; + } + break; + case ISCSI_TM_FUNC_ABORT_TASK: + /* + * the caller has already checked if the task + * they want to abort was in the pending queue so if + * we are here the cmd pdu has gone out already, and + * we will only hit this for data-outs + */ + if (opcode == ISCSI_OP_SCSI_DATA_OUT && + task->hdr_itt == tmf->rtt) { + ISCSI_DBG_SESSION(conn->session, + "Preventing task %x/%x from sending " + "data-out due to abort task in " + "progress\n", task->itt, + task->hdr_itt); + return -EACCES; + } + break; + } + + return 0; +} + +/** * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu * @task: iscsi task * @@ -282,6 +364,10 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) itt_t itt; int rc; + rc = iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_CMD); + if (rc) + return rc; + if (conn->session->tt->alloc_pdu) { rc = conn->session->tt->alloc_pdu(task, ISCSI_OP_SCSI_CMD); if (rc) @@ -1366,6 +1452,7 @@ EXPORT_SYMBOL_GPL(iscsi_requeue_task); **/ static int iscsi_data_xmit(struct iscsi_conn *conn) { + struct iscsi_task *task; int rc = 0; spin_lock_bh(&conn->session->lock); @@ -1403,11 +1490,8 @@ check_mgmt: /* process pending command queue */ while (!list_empty(&conn->cmdqueue)) { - if (conn->tmf_state == TMF_QUEUED) - break; - - conn->task = list_entry(conn->cmdqueue.next, - struct iscsi_task, running); + conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task, + running); list_del_init(&conn->task->running); if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { fail_scsi_task(conn->task, DID_IMM_RETRY); @@ -1415,7 +1499,7 @@ check_mgmt: } rc = iscsi_prep_scsi_cmd_pdu(conn->task); if (rc) { - if (rc == -ENOMEM) { + if (rc == -ENOMEM || rc == -EACCES) { list_add_tail(&conn->task->running, &conn->cmdqueue); conn->task = NULL; @@ -1437,17 +1521,18 @@ check_mgmt: } while (!list_empty(&conn->requeue)) { - if (conn->session->fast_abort && conn->tmf_state != TMF_INITIAL) - break; - /* * we always do fastlogout - conn stop code will clean up. */ if (conn->session->state == ISCSI_STATE_LOGGING_OUT) break; - conn->task = list_entry(conn->requeue.next, - struct iscsi_task, running); + task = list_entry(conn->requeue.next, struct iscsi_task, + running); + if (iscsi_check_tmf_restrictions(task, ISCSI_OP_SCSI_DATA_OUT)) + break; + + conn->task = task; list_del_init(&conn->task->running); conn->task->state = ISCSI_TASK_RUNNING; rc = iscsi_xmit_task(conn); @@ -1600,7 +1685,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) if (!ihost->workq) { reason = iscsi_prep_scsi_cmd_pdu(task); if (reason) { - if (reason == -ENOMEM) { + if (reason == -ENOMEM || reason == -EACCES) { reason = FAILURE_OOM; goto prepd_reject; } else { @@ -2120,6 +2205,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) spin_lock_bh(&session->lock); fail_scsi_task(task, DID_ABORT); conn->tmf_state = TMF_INITIAL; + memset(hdr, 0, sizeof(*hdr)); spin_unlock_bh(&session->lock); iscsi_start_tx(conn); goto success_unlocked; @@ -2130,6 +2216,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) case TMF_NOT_FOUND: if (!sc->SCp.ptr) { conn->tmf_state = TMF_INITIAL; + memset(hdr, 0, sizeof(*hdr)); /* task completed before tmf abort response */ ISCSI_DBG_EH(session, "sc completed while abort in " "progress\n"); @@ -2224,6 +2311,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) iscsi_suspend_tx(conn); spin_lock_bh(&session->lock); + memset(hdr, 0, sizeof(*hdr)); fail_scsi_tasks(conn, sc->device->lun, DID_ERROR); conn->tmf_state = TMF_INITIAL; spin_unlock_bh(&session->lock); @@ -2868,6 +2956,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, spin_lock_bh(&session->lock); fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED); fail_mgmt_tasks(session, conn); + memset(&conn->tmhdr, 0, sizeof(conn->tmhdr)); spin_unlock_bh(&session->lock); mutex_unlock(&session->eh_mutex); } diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index f2a2c11..dd0a52c 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h @@ -279,6 +279,8 @@ struct iscsi_tm { #define ISCSI_TM_FUNC_TARGET_COLD_RESET 7 #define ISCSI_TM_FUNC_TASK_REASSIGN 8 +#define ISCSI_TM_FUNC_VALUE(hdr) ((hdr)->flags & ISCSI_FLAG_TM_FUNC_MASK) + /* SCSI Task Management Response Header */ struct iscsi_tm_rsp { uint8_t opcode; -- 1.6.2.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7] libiscsi: add warm target reset tmf support 2009-11-11 22:34 ` [PATCH 3/7] libiscsi: Check TMF state before sending PDU michaelc @ 2009-11-11 22:34 ` michaelc 2009-11-11 22:34 ` [PATCH 5/7] iscsi class: modify handling of replacement timeout michaelc 0 siblings, 1 reply; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi; +Cc: Mike Christie From: Mike Christie <michaelc@cs.wisc.edu> This implements warm target reset tmf support for the scsi-ml target reset callback. Previously we would just drop the session in that callback. This patch will now try a target reset and if that fails drop the session. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> --- drivers/scsi/be2iscsi/be_main.c | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/cxgb3i/cxgb3i_iscsi.c | 2 +- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/libiscsi.c | 251 +++++++++++++++++++++++++---------- drivers/scsi/scsi_transport_iscsi.c | 4 +- include/scsi/iscsi_if.h | 3 + include/scsi/libiscsi.h | 1 + 8 files changed, 190 insertions(+), 77 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index d15df07..1a557fa 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -3859,7 +3859,7 @@ struct iscsi_transport beiscsi_iscsi_transport = { ISCSI_USERNAME | ISCSI_PASSWORD | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | - ISCSI_LU_RESET_TMO | + ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | ISCSI_PING_TMO | ISCSI_RECV_TMO | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 89e84c3..070118a 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -2028,7 +2028,7 @@ struct iscsi_transport bnx2i_iscsi_transport = { ISCSI_USERNAME | ISCSI_PASSWORD | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | - ISCSI_LU_RESET_TMO | + ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | ISCSI_PING_TMO | ISCSI_RECV_TMO | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME, diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index 2631bdd..969c831 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c @@ -937,7 +937,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = { ISCSI_USERNAME | ISCSI_PASSWORD | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | - ISCSI_LU_RESET_TMO | + ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | ISCSI_PING_TMO | ISCSI_RECV_TMO | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index edc49ca..517da3f 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -903,7 +903,7 @@ static struct iscsi_transport iscsi_sw_tcp_transport = { ISCSI_USERNAME | ISCSI_PASSWORD | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | - ISCSI_LU_RESET_TMO | + ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | ISCSI_PING_TMO | ISCSI_RECV_TMO | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index b6ffdc5..07ec997 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -298,17 +298,18 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode) hdr_lun = scsilun_to_int((struct scsi_lun *)tmf->lun); if (hdr_lun != task->sc->device->lun) return 0; - + /* fall through */ + case ISCSI_TM_FUNC_TARGET_WARM_RESET: /* * Fail all SCSI cmd PDUs */ if (opcode != ISCSI_OP_SCSI_DATA_OUT) { iscsi_conn_printk(KERN_INFO, conn, "task [op %x/%x itt " - "0x%x/0x%x lun %u] " + "0x%x/0x%x] " "rejected.\n", task->hdr->opcode, opcode, - task->itt, task->hdr_itt, hdr_lun); + task->itt, task->hdr_itt); return -EACCES; } /* @@ -318,10 +319,9 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode) if (conn->session->fast_abort) { iscsi_conn_printk(KERN_INFO, conn, "task [op %x/%x itt " - "0x%x/0x%x lun %u] " - "fast abort.\n", + "0x%x/0x%x] fast abort.\n", task->hdr->opcode, opcode, - task->itt, task->hdr_itt, hdr_lun); + task->itt, task->hdr_itt); return -EACCES; } break; @@ -1757,72 +1757,6 @@ int iscsi_target_alloc(struct scsi_target *starget) } EXPORT_SYMBOL_GPL(iscsi_target_alloc); -void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) -{ - struct iscsi_session *session = cls_session->dd_data; - - spin_lock_bh(&session->lock); - if (session->state != ISCSI_STATE_LOGGED_IN) { - session->state = ISCSI_STATE_RECOVERY_FAILED; - if (session->leadconn) - wake_up(&session->leadconn->ehwait); - } - spin_unlock_bh(&session->lock); -} -EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); - -int iscsi_eh_target_reset(struct scsi_cmnd *sc) -{ - struct iscsi_cls_session *cls_session; - struct iscsi_session *session; - struct iscsi_conn *conn; - - cls_session = starget_to_session(scsi_target(sc->device)); - session = cls_session->dd_data; - conn = session->leadconn; - - mutex_lock(&session->eh_mutex); - spin_lock_bh(&session->lock); - if (session->state == ISCSI_STATE_TERMINATE) { -failed: - ISCSI_DBG_EH(session, - "failing target reset: Could not log back into " - "target [age %d]\n", - session->age); - spin_unlock_bh(&session->lock); - mutex_unlock(&session->eh_mutex); - return FAILED; - } - - spin_unlock_bh(&session->lock); - mutex_unlock(&session->eh_mutex); - /* - * we drop the lock here but the leadconn cannot be destoyed while - * we are in the scsi eh - */ - iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); - - ISCSI_DBG_EH(session, "wait for relogin\n"); - wait_event_interruptible(conn->ehwait, - session->state == ISCSI_STATE_TERMINATE || - session->state == ISCSI_STATE_LOGGED_IN || - session->state == ISCSI_STATE_RECOVERY_FAILED); - if (signal_pending(current)) - flush_signals(current); - - mutex_lock(&session->eh_mutex); - spin_lock_bh(&session->lock); - if (session->state == ISCSI_STATE_LOGGED_IN) { - ISCSI_DBG_EH(session, - "target reset succeeded\n"); - } else - goto failed; - spin_unlock_bh(&session->lock); - mutex_unlock(&session->eh_mutex); - return SUCCESS; -} -EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); - static void iscsi_tmf_timedout(unsigned long data) { struct iscsi_conn *conn = (struct iscsi_conn *)data; @@ -2329,6 +2263,172 @@ done: } EXPORT_SYMBOL_GPL(iscsi_eh_device_reset); +void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) +{ + struct iscsi_session *session = cls_session->dd_data; + + spin_lock_bh(&session->lock); + if (session->state != ISCSI_STATE_LOGGED_IN) { + session->state = ISCSI_STATE_RECOVERY_FAILED; + if (session->leadconn) + wake_up(&session->leadconn->ehwait); + } + spin_unlock_bh(&session->lock); +} +EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); + +/** + * iscsi_eh_session_reset - drop session and attempt relogin + * @sc: scsi command + * + * This function will wait for a relogin, session termination from + * userspace, or a recovery/replacement timeout. + */ +static int iscsi_eh_session_reset(struct scsi_cmnd *sc) +{ + struct iscsi_cls_session *cls_session; + struct iscsi_session *session; + struct iscsi_conn *conn; + + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; + conn = session->leadconn; + + mutex_lock(&session->eh_mutex); + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_TERMINATE) { +failed: + ISCSI_DBG_EH(session, + "failing session reset: Could not log back into " + "%s, %s [age %d]\n", session->targetname, + conn->persistent_address, session->age); + spin_unlock_bh(&session->lock); + mutex_unlock(&session->eh_mutex); + return FAILED; + } + + spin_unlock_bh(&session->lock); + mutex_unlock(&session->eh_mutex); + /* + * we drop the lock here but the leadconn cannot be destoyed while + * we are in the scsi eh + */ + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + + ISCSI_DBG_EH(session, "wait for relogin\n"); + wait_event_interruptible(conn->ehwait, + session->state == ISCSI_STATE_TERMINATE || + session->state == ISCSI_STATE_LOGGED_IN || + session->state == ISCSI_STATE_RECOVERY_FAILED); + if (signal_pending(current)) + flush_signals(current); + + mutex_lock(&session->eh_mutex); + spin_lock_bh(&session->lock); + if (session->state == ISCSI_STATE_LOGGED_IN) { + ISCSI_DBG_EH(session, + "session reset succeeded for %s,%s\n", + session->targetname, conn->persistent_address); + } else + goto failed; + spin_unlock_bh(&session->lock); + mutex_unlock(&session->eh_mutex); + return SUCCESS; +} + +static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) +{ + memset(hdr, 0, sizeof(*hdr)); + hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; + hdr->flags = ISCSI_TM_FUNC_TARGET_WARM_RESET & ISCSI_FLAG_TM_FUNC_MASK; + hdr->flags |= ISCSI_FLAG_CMD_FINAL; + hdr->rtt = RESERVED_ITT; +} + +/** + * iscsi_eh_target_reset - reset target + * @sc: scsi command + * + * This will attempt to send a warm target reset. If that fails + * then we will drop the session and attempt ERL0 recovery. + */ +int iscsi_eh_target_reset(struct scsi_cmnd *sc) +{ + struct iscsi_cls_session *cls_session; + struct iscsi_session *session; + struct iscsi_conn *conn; + struct iscsi_tm *hdr; + int rc = FAILED; + + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; + + ISCSI_DBG_EH(session, "tgt Reset [sc %p tgt %s]\n", sc, + session->targetname); + + mutex_lock(&session->eh_mutex); + spin_lock_bh(&session->lock); + /* + * Just check if we are not logged in. We cannot check for + * the phase because the reset could come from a ioctl. + */ + if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) + goto unlock; + conn = session->leadconn; + + /* only have one tmf outstanding at a time */ + if (conn->tmf_state != TMF_INITIAL) + goto unlock; + conn->tmf_state = TMF_QUEUED; + + hdr = &conn->tmhdr; + iscsi_prep_tgt_reset_pdu(sc, hdr); + + if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, + session->tgt_reset_timeout)) { + rc = FAILED; + goto unlock; + } + + switch (conn->tmf_state) { + case TMF_SUCCESS: + break; + case TMF_TIMEDOUT: + spin_unlock_bh(&session->lock); + iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); + goto done; + default: + conn->tmf_state = TMF_INITIAL; + goto unlock; + } + + rc = SUCCESS; + spin_unlock_bh(&session->lock); + + iscsi_suspend_tx(conn); + + spin_lock_bh(&session->lock); + memset(hdr, 0, sizeof(*hdr)); + fail_scsi_tasks(conn, -1, DID_ERROR); + conn->tmf_state = TMF_INITIAL; + spin_unlock_bh(&session->lock); + + iscsi_start_tx(conn); + goto done; + +unlock: + spin_unlock_bh(&session->lock); +done: + ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname, + rc == SUCCESS ? "SUCCESS" : "FAILED"); + mutex_unlock(&session->eh_mutex); + + if (rc == FAILED) + rc = iscsi_eh_session_reset(sc); + return rc; +} +EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); + /* * Pre-allocate a pool of @max items of @item_size. By default, the pool * should be accessed via kfifo_{get,put} on q->queue. @@ -2595,6 +2695,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, session->host = shost; session->state = ISCSI_STATE_FREE; session->fast_abort = 1; + session->tgt_reset_timeout = 30; session->lu_reset_timeout = 15; session->abort_timeout = 10; session->scsi_cmds_max = scsi_cmds; @@ -3033,6 +3134,9 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn, case ISCSI_PARAM_LU_RESET_TMO: sscanf(buf, "%d", &session->lu_reset_timeout); break; + case ISCSI_PARAM_TGT_RESET_TMO: + sscanf(buf, "%d", &session->tgt_reset_timeout); + break; case ISCSI_PARAM_PING_TMO: sscanf(buf, "%d", &conn->ping_timeout); break; @@ -3132,6 +3236,9 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session, case ISCSI_PARAM_LU_RESET_TMO: len = sprintf(buf, "%d\n", session->lu_reset_timeout); break; + case ISCSI_PARAM_TGT_RESET_TMO: + len = sprintf(buf, "%d\n", session->tgt_reset_timeout); + break; case ISCSI_PARAM_INITIAL_R2T_EN: len = sprintf(buf, "%d\n", session->initial_r2t_en); break; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index ad897df..dc04ca1 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -30,7 +30,7 @@ #include <scsi/scsi_transport_iscsi.h> #include <scsi/iscsi_if.h> -#define ISCSI_SESSION_ATTRS 21 +#define ISCSI_SESSION_ATTRS 22 #define ISCSI_CONN_ATTRS 13 #define ISCSI_HOST_ATTRS 4 @@ -1759,6 +1759,7 @@ iscsi_session_attr(password_in, ISCSI_PARAM_PASSWORD_IN, 1); iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 0); iscsi_session_attr(abort_tmo, ISCSI_PARAM_ABORT_TMO, 0); iscsi_session_attr(lu_reset_tmo, ISCSI_PARAM_LU_RESET_TMO, 0); +iscsi_session_attr(tgt_reset_tmo, ISCSI_PARAM_TGT_RESET_TMO, 0); iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0); iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0) @@ -2000,6 +2001,7 @@ iscsi_register_transport(struct iscsi_transport *tt) SETUP_SESSION_RD_ATTR(fast_abort, ISCSI_FAST_ABORT); SETUP_SESSION_RD_ATTR(abort_tmo, ISCSI_ABORT_TMO); SETUP_SESSION_RD_ATTR(lu_reset_tmo,ISCSI_LU_RESET_TMO); + SETUP_SESSION_RD_ATTR(tgt_reset_tmo,ISCSI_TGT_RESET_TMO); SETUP_SESSION_RD_ATTR(ifacename, ISCSI_IFACE_NAME); SETUP_SESSION_RD_ATTR(initiatorname, ISCSI_INITIATOR_NAME); SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index d67dda2..66d377b 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -311,6 +311,8 @@ enum iscsi_param { ISCSI_PARAM_IFACE_NAME, ISCSI_PARAM_ISID, ISCSI_PARAM_INITIATOR_NAME, + + ISCSI_PARAM_TGT_RESET_TMO, /* must always be last */ ISCSI_PARAM_MAX, }; @@ -350,6 +352,7 @@ enum iscsi_param { #define ISCSI_IFACE_NAME (1ULL << ISCSI_PARAM_IFACE_NAME) #define ISCSI_ISID (1ULL << ISCSI_PARAM_ISID) #define ISCSI_INITIATOR_NAME (1ULL << ISCSI_PARAM_INITIATOR_NAME) +#define ISCSI_TGT_RESET_TMO (1ULL << ISCSI_PARAM_TGT_RESET_TMO) /* iSCSI HBA params */ enum iscsi_host_param { diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 2db2bc2..7394e3b 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -267,6 +267,7 @@ struct iscsi_session { /* configuration */ int abort_timeout; int lu_reset_timeout; + int tgt_reset_timeout; int initial_r2t_en; unsigned max_r2t; int imm_data_en; -- 1.6.2.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7] iscsi class: modify handling of replacement timeout 2009-11-11 22:34 ` [PATCH 4/7] libiscsi: add warm target reset tmf support michaelc @ 2009-11-11 22:34 ` michaelc 2009-11-11 22:34 ` [PATCH 6/7] iser: set tgt and lu reset timeout michaelc 0 siblings, 1 reply; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi; +Cc: Mike Christie From: Mike Christie <michaelc@cs.wisc.edu> This patch modifies the replacement/recovery_timeout so it works more like the fc fast io fail tmo. If userspace tries to set the replacement/recovery_timeout to less than zero, we will turn off the forced recovery cleanup. If userspace sets the value to 0 then we will force the recovery cleanup immediately. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> --- drivers/scsi/scsi_transport_iscsi.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index dc04ca1..ea3892e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -627,8 +627,10 @@ static void __iscsi_block_session(struct work_struct *work) spin_unlock_irqrestore(&session->lock, flags); scsi_target_block(&session->dev); ISCSI_DBG_TRANS_SESSION(session, "Completed SCSI target blocking\n"); - queue_delayed_work(iscsi_eh_timer_workq, &session->recovery_work, - session->recovery_tmo * HZ); + if (session->recovery_tmo >= 0) + queue_delayed_work(iscsi_eh_timer_workq, + &session->recovery_work, + session->recovery_tmo * HZ); } void iscsi_block_session(struct iscsi_cls_session *session) @@ -1348,8 +1350,7 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) switch (ev->u.set_param.param) { case ISCSI_PARAM_SESS_RECOVERY_TMO: sscanf(data, "%d", &value); - if (value != 0) - session->recovery_tmo = value; + session->recovery_tmo = value; break; default: err = transport->set_param(conn, ev->u.set_param.param, -- 1.6.2.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7] iser: set tgt and lu reset timeout 2009-11-11 22:34 ` [PATCH 5/7] iscsi class: modify handling of replacement timeout michaelc @ 2009-11-11 22:34 ` michaelc 2009-11-11 22:34 ` [PATCH 7/7] libiscsi: hook into ramp up/down handling michaelc 0 siblings, 1 reply; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi; +Cc: Mike Christie From: Mike Christie <michaelc@cs.wisc.edu> When iser enabled lu reset support it did not set the bit to allow userspace to get/set the timeout. This sets the tgt and lu reset timeout bits. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> --- drivers/infiniband/ulp/iser/iscsi_iser.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index add9188..5f7a6fc 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -625,6 +625,7 @@ static struct iscsi_transport iscsi_iser_transport = { ISCSI_USERNAME | ISCSI_PASSWORD | ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | + ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | ISCSI_PING_TMO | ISCSI_RECV_TMO | ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, .host_param_mask = ISCSI_HOST_HWADDRESS | -- 1.6.2.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7] libiscsi: hook into ramp up/down handling 2009-11-11 22:34 ` [PATCH 6/7] iser: set tgt and lu reset timeout michaelc @ 2009-11-11 22:34 ` michaelc 0 siblings, 0 replies; 9+ messages in thread From: michaelc @ 2009-11-11 22:34 UTC (permalink / raw) To: linux-scsi; +Cc: Mike Christie From: Mike Christie <michaelc@cs.wisc.edu> It is rare to get a queue full with iscsi, because targets seem to just reduce the iscsi cmd window. However, there is at least one iscsi target that will throw a queue full when overloaded. This hooks the iscsi code in to the ramp up/down code, so we can handle it. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> --- drivers/scsi/libiscsi.c | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 07ec997..b7689f3 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1739,10 +1739,19 @@ EXPORT_SYMBOL_GPL(iscsi_queuecommand); int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason) { - if (reason != SCSI_QDEPTH_DEFAULT) + switch (reason) { + case SCSI_QDEPTH_DEFAULT: + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); + break; + case SCSI_QDEPTH_QFULL: + scsi_track_queue_full(sdev, depth); + break; + case SCSI_QDEPTH_RAMP_UP: + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); + break; + default: return -EOPNOTSUPP; - - scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); + } return sdev->queue_depth; } EXPORT_SYMBOL_GPL(iscsi_change_queue_depth); -- 1.6.2.2 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/7] bnx2i: use common iscsi suspend queue 2009-11-11 22:34 ` [PATCH 1/7] bnx2i: use common iscsi suspend queue michaelc 2009-11-11 22:34 ` [PATCH 2/7] libiscsi: fix login/text checks in pdu injection code michaelc @ 2009-11-12 2:00 ` Anil Veerabhadrappa 1 sibling, 0 replies; 9+ messages in thread From: Anil Veerabhadrappa @ 2009-11-12 2:00 UTC (permalink / raw) To: michaelc@cs.wisc.edu; +Cc: linux-scsi@vger.kernel.org On Wed, 2009-11-11 at 14:34 -0800, michaelc@cs.wisc.edu wrote: > From: Mike Christie <michaelc@cs.wisc.edu> > > This just has bnx2i use the iscsi_suspend_queue helper. > > The suspend works as follows: > > When ep_poll has succeeed iscsid will call conn_bind, the LLD will > then call iscsi_conn_bind which will clear the suspend bit. > When ep_disconnect is called (or if there is a conn error) we set > the suspend bit. For the ep_disconnect case I added a helper > in the previous kernel that will take the session lock to make sure > iscsi_queuecommand/xmit_task is not running and it will set > the suspend bit. > > Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> > --- > drivers/scsi/bnx2i/bnx2i.h | 1 - > drivers/scsi/bnx2i/bnx2i_iscsi.c | 8 +------- > 2 files changed, 1 insertions(+), 8 deletions(-) > Looks good. Acked-by: Anil Veerabhadrappa <anilgv@broadcom.com> > diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h > index 5edde1a..2b973f3 100644 > --- a/drivers/scsi/bnx2i/bnx2i.h > +++ b/drivers/scsi/bnx2i/bnx2i.h > @@ -232,7 +232,6 @@ struct bnx2i_conn { > struct iscsi_cls_conn *cls_conn; > struct bnx2i_hba *hba; > struct completion cmd_cleanup_cmpl; > - int is_bound; > > u32 iscsi_conn_cid; > #define BNX2I_CID_RESERVED 0x5AFF > diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c > index cafb888..89e84c3 100644 > --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c > +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c > @@ -1161,9 +1161,6 @@ static int bnx2i_task_xmit(struct iscsi_task *task) > struct bnx2i_cmd *cmd = task->dd_data; > struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; > > - if (!bnx2i_conn->is_bound) > - return -ENOTCONN; > - > /* > * If there is no scsi_cmnd this must be a mgmt task > */ > @@ -1371,7 +1368,6 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session, > bnx2i_conn->ep = bnx2i_ep; > bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid; > bnx2i_conn->fw_cid = bnx2i_ep->ep_cid; > - bnx2i_conn->is_bound = 1; > > ret_code = bnx2i_bind_conn_to_iscsi_cid(hba, bnx2i_conn, > bnx2i_ep->ep_iscsi_cid); > @@ -1896,9 +1892,7 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep) > conn = bnx2i_conn->cls_conn->dd_data; > session = conn->session; > > - spin_lock_bh(&session->lock); > - bnx2i_conn->is_bound = 0; > - spin_unlock_bh(&session->lock); > + iscsi_suspend_queue(conn); > } > > hba = bnx2i_ep->hba; ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-11-12 2:00 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-11-11 22:34 iscsi fixes and features for 2.6.33 michaelc 2009-11-11 22:34 ` [PATCH 1/7] bnx2i: use common iscsi suspend queue michaelc 2009-11-11 22:34 ` [PATCH 2/7] libiscsi: fix login/text checks in pdu injection code michaelc 2009-11-11 22:34 ` [PATCH 3/7] libiscsi: Check TMF state before sending PDU michaelc 2009-11-11 22:34 ` [PATCH 4/7] libiscsi: add warm target reset tmf support michaelc 2009-11-11 22:34 ` [PATCH 5/7] iscsi class: modify handling of replacement timeout michaelc 2009-11-11 22:34 ` [PATCH 6/7] iser: set tgt and lu reset timeout michaelc 2009-11-11 22:34 ` [PATCH 7/7] libiscsi: hook into ramp up/down handling michaelc 2009-11-12 2:00 ` [PATCH 1/7] bnx2i: use common iscsi suspend queue Anil Veerabhadrappa
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox