diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 7 | ||||
| -rw-r--r-- | drivers/scsi/libiscsi.c | 60 | ||||
| -rw-r--r-- | drivers/scsi/libiscsi_tcp.c | 4 |
3 files changed, 39 insertions, 32 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index ffbe0c76bc11..0ba6ec876296 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
| @@ -257,11 +257,8 @@ static void iscsi_iser_cleanup_task(struct iscsi_task *task) | |||
| 257 | { | 257 | { |
| 258 | struct iscsi_iser_task *iser_task = task->dd_data; | 258 | struct iscsi_iser_task *iser_task = task->dd_data; |
| 259 | 259 | ||
| 260 | /* | 260 | /* mgmt tasks do not need special cleanup */ |
| 261 | * mgmt tasks do not need special cleanup and we do not | 261 | if (!task->sc) |
| 262 | * allocate anything in the init task callout | ||
| 263 | */ | ||
| 264 | if (!task->sc || task->state == ISCSI_TASK_PENDING) | ||
| 265 | return; | 262 | return; |
| 266 | 263 | ||
| 267 | if (iser_task->status == ISER_TASK_STATUS_STARTED) { | 264 | if (iser_task->status == ISER_TASK_STATUS_STARTED) { |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index dafa054537f6..b00be6c3efc1 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -443,18 +443,20 @@ EXPORT_SYMBOL_GPL(iscsi_put_task); | |||
| 443 | /** | 443 | /** |
| 444 | * iscsi_complete_task - finish a task | 444 | * iscsi_complete_task - finish a task |
| 445 | * @task: iscsi cmd task | 445 | * @task: iscsi cmd task |
| 446 | * @state: state to complete task with | ||
| 446 | * | 447 | * |
| 447 | * Must be called with session lock. | 448 | * Must be called with session lock. |
| 448 | */ | 449 | */ |
| 449 | static void iscsi_complete_task(struct iscsi_task *task) | 450 | static void iscsi_complete_task(struct iscsi_task *task, int state) |
| 450 | { | 451 | { |
| 451 | struct iscsi_conn *conn = task->conn; | 452 | struct iscsi_conn *conn = task->conn; |
| 452 | 453 | ||
| 453 | if (task->state == ISCSI_TASK_COMPLETED) | 454 | if (task->state == ISCSI_TASK_COMPLETED || |
| 455 | task->state == ISCSI_TASK_ABRT_TMF || | ||
| 456 | task->state == ISCSI_TASK_ABRT_SESS_RECOV) | ||
| 454 | return; | 457 | return; |
| 455 | WARN_ON_ONCE(task->state == ISCSI_TASK_FREE); | 458 | WARN_ON_ONCE(task->state == ISCSI_TASK_FREE); |
| 456 | 459 | task->state = state; | |
| 457 | task->state = ISCSI_TASK_COMPLETED; | ||
| 458 | 460 | ||
| 459 | if (!list_empty(&task->running)) | 461 | if (!list_empty(&task->running)) |
| 460 | list_del_init(&task->running); | 462 | list_del_init(&task->running); |
| @@ -478,6 +480,7 @@ static void fail_scsi_task(struct iscsi_task *task, int err) | |||
| 478 | { | 480 | { |
| 479 | struct iscsi_conn *conn = task->conn; | 481 | struct iscsi_conn *conn = task->conn; |
| 480 | struct scsi_cmnd *sc; | 482 | struct scsi_cmnd *sc; |
| 483 | int state; | ||
| 481 | 484 | ||
| 482 | /* | 485 | /* |
| 483 | * if a command completes and we get a successful tmf response | 486 | * if a command completes and we get a successful tmf response |
| @@ -488,14 +491,20 @@ static void fail_scsi_task(struct iscsi_task *task, int err) | |||
| 488 | if (!sc) | 491 | if (!sc) |
| 489 | return; | 492 | return; |
| 490 | 493 | ||
| 491 | if (task->state == ISCSI_TASK_PENDING) | 494 | if (task->state == ISCSI_TASK_PENDING) { |
| 492 | /* | 495 | /* |
| 493 | * cmd never made it to the xmit thread, so we should not count | 496 | * cmd never made it to the xmit thread, so we should not count |
| 494 | * the cmd in the sequencing | 497 | * the cmd in the sequencing |
| 495 | */ | 498 | */ |
| 496 | conn->session->queued_cmdsn--; | 499 | conn->session->queued_cmdsn--; |
| 500 | /* it was never sent so just complete like normal */ | ||
| 501 | state = ISCSI_TASK_COMPLETED; | ||
| 502 | } else if (err == DID_TRANSPORT_DISRUPTED) | ||
| 503 | state = ISCSI_TASK_ABRT_SESS_RECOV; | ||
| 504 | else | ||
| 505 | state = ISCSI_TASK_ABRT_TMF; | ||
| 497 | 506 | ||
| 498 | sc->result = err; | 507 | sc->result = err << 16; |
| 499 | if (!scsi_bidi_cmnd(sc)) | 508 | if (!scsi_bidi_cmnd(sc)) |
| 500 | scsi_set_resid(sc, scsi_bufflen(sc)); | 509 | scsi_set_resid(sc, scsi_bufflen(sc)); |
| 501 | else { | 510 | else { |
| @@ -503,7 +512,7 @@ static void fail_scsi_task(struct iscsi_task *task, int err) | |||
| 503 | scsi_in(sc)->resid = scsi_in(sc)->length; | 512 | scsi_in(sc)->resid = scsi_in(sc)->length; |
| 504 | } | 513 | } |
| 505 | 514 | ||
| 506 | iscsi_complete_task(task); | 515 | iscsi_complete_task(task, state); |
| 507 | } | 516 | } |
| 508 | 517 | ||
| 509 | static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, | 518 | static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, |
| @@ -731,7 +740,7 @@ out: | |||
| 731 | ISCSI_DBG_SESSION(session, "cmd rsp done [sc %p res %d itt 0x%x]\n", | 740 | ISCSI_DBG_SESSION(session, "cmd rsp done [sc %p res %d itt 0x%x]\n", |
| 732 | sc, sc->result, task->itt); | 741 | sc, sc->result, task->itt); |
| 733 | conn->scsirsp_pdus_cnt++; | 742 | conn->scsirsp_pdus_cnt++; |
| 734 | iscsi_complete_task(task); | 743 | iscsi_complete_task(task, ISCSI_TASK_COMPLETED); |
| 735 | } | 744 | } |
| 736 | 745 | ||
| 737 | /** | 746 | /** |
| @@ -769,7 +778,7 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 769 | "[sc %p res %d itt 0x%x]\n", | 778 | "[sc %p res %d itt 0x%x]\n", |
| 770 | sc, sc->result, task->itt); | 779 | sc, sc->result, task->itt); |
| 771 | conn->scsirsp_pdus_cnt++; | 780 | conn->scsirsp_pdus_cnt++; |
| 772 | iscsi_complete_task(task); | 781 | iscsi_complete_task(task, ISCSI_TASK_COMPLETED); |
| 773 | } | 782 | } |
| 774 | 783 | ||
| 775 | static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | 784 | static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) |
| @@ -990,7 +999,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 990 | } | 999 | } |
| 991 | 1000 | ||
| 992 | iscsi_tmf_rsp(conn, hdr); | 1001 | iscsi_tmf_rsp(conn, hdr); |
| 993 | iscsi_complete_task(task); | 1002 | iscsi_complete_task(task, ISCSI_TASK_COMPLETED); |
| 994 | break; | 1003 | break; |
| 995 | case ISCSI_OP_NOOP_IN: | 1004 | case ISCSI_OP_NOOP_IN: |
| 996 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | 1005 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); |
| @@ -1008,7 +1017,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 1008 | goto recv_pdu; | 1017 | goto recv_pdu; |
| 1009 | 1018 | ||
| 1010 | mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout); | 1019 | mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout); |
| 1011 | iscsi_complete_task(task); | 1020 | iscsi_complete_task(task, ISCSI_TASK_COMPLETED); |
| 1012 | break; | 1021 | break; |
| 1013 | default: | 1022 | default: |
| 1014 | rc = ISCSI_ERR_BAD_OPCODE; | 1023 | rc = ISCSI_ERR_BAD_OPCODE; |
| @@ -1020,7 +1029,7 @@ out: | |||
| 1020 | recv_pdu: | 1029 | recv_pdu: |
| 1021 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) | 1030 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) |
| 1022 | rc = ISCSI_ERR_CONN_FAILED; | 1031 | rc = ISCSI_ERR_CONN_FAILED; |
| 1023 | iscsi_complete_task(task); | 1032 | iscsi_complete_task(task, ISCSI_TASK_COMPLETED); |
| 1024 | return rc; | 1033 | return rc; |
| 1025 | } | 1034 | } |
| 1026 | EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); | 1035 | EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); |
| @@ -1262,7 +1271,7 @@ check_mgmt: | |||
| 1262 | struct iscsi_task, running); | 1271 | struct iscsi_task, running); |
| 1263 | list_del_init(&conn->task->running); | 1272 | list_del_init(&conn->task->running); |
| 1264 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { | 1273 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { |
| 1265 | fail_scsi_task(conn->task, DID_IMM_RETRY << 16); | 1274 | fail_scsi_task(conn->task, DID_IMM_RETRY); |
| 1266 | continue; | 1275 | continue; |
| 1267 | } | 1276 | } |
| 1268 | rc = iscsi_prep_scsi_cmd_pdu(conn->task); | 1277 | rc = iscsi_prep_scsi_cmd_pdu(conn->task); |
| @@ -1273,7 +1282,7 @@ check_mgmt: | |||
| 1273 | conn->task = NULL; | 1282 | conn->task = NULL; |
| 1274 | goto again; | 1283 | goto again; |
| 1275 | } else | 1284 | } else |
| 1276 | fail_scsi_task(conn->task, DID_ABORT << 16); | 1285 | fail_scsi_task(conn->task, DID_ABORT); |
| 1277 | continue; | 1286 | continue; |
| 1278 | } | 1287 | } |
| 1279 | rc = iscsi_xmit_task(conn); | 1288 | rc = iscsi_xmit_task(conn); |
| @@ -1469,7 +1478,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
| 1469 | 1478 | ||
| 1470 | prepd_reject: | 1479 | prepd_reject: |
| 1471 | sc->scsi_done = NULL; | 1480 | sc->scsi_done = NULL; |
| 1472 | iscsi_complete_task(task); | 1481 | iscsi_complete_task(task, ISCSI_TASK_COMPLETED); |
| 1473 | reject: | 1482 | reject: |
| 1474 | spin_unlock(&session->lock); | 1483 | spin_unlock(&session->lock); |
| 1475 | ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n", | 1484 | ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n", |
| @@ -1479,7 +1488,7 @@ reject: | |||
| 1479 | 1488 | ||
| 1480 | prepd_fault: | 1489 | prepd_fault: |
| 1481 | sc->scsi_done = NULL; | 1490 | sc->scsi_done = NULL; |
| 1482 | iscsi_complete_task(task); | 1491 | iscsi_complete_task(task, ISCSI_TASK_COMPLETED); |
| 1483 | fault: | 1492 | fault: |
| 1484 | spin_unlock(&session->lock); | 1493 | spin_unlock(&session->lock); |
| 1485 | ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n", | 1494 | ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n", |
| @@ -1665,7 +1674,7 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, unsigned lun, | |||
| 1665 | ISCSI_DBG_SESSION(conn->session, | 1674 | ISCSI_DBG_SESSION(conn->session, |
| 1666 | "failing sc %p itt 0x%x state %d\n", | 1675 | "failing sc %p itt 0x%x state %d\n", |
| 1667 | task->sc, task->itt, task->state); | 1676 | task->sc, task->itt, task->state); |
| 1668 | fail_scsi_task(task, error << 16); | 1677 | fail_scsi_task(task, error); |
| 1669 | } | 1678 | } |
| 1670 | } | 1679 | } |
| 1671 | 1680 | ||
| @@ -1868,7 +1877,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 1868 | } | 1877 | } |
| 1869 | 1878 | ||
| 1870 | if (task->state == ISCSI_TASK_PENDING) { | 1879 | if (task->state == ISCSI_TASK_PENDING) { |
| 1871 | fail_scsi_task(task, DID_ABORT << 16); | 1880 | fail_scsi_task(task, DID_ABORT); |
| 1872 | goto success; | 1881 | goto success; |
| 1873 | } | 1882 | } |
| 1874 | 1883 | ||
| @@ -1899,7 +1908,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 1899 | * then sent more data for the cmd. | 1908 | * then sent more data for the cmd. |
| 1900 | */ | 1909 | */ |
| 1901 | spin_lock(&session->lock); | 1910 | spin_lock(&session->lock); |
| 1902 | fail_scsi_task(task, DID_ABORT << 16); | 1911 | fail_scsi_task(task, DID_ABORT); |
| 1903 | conn->tmf_state = TMF_INITIAL; | 1912 | conn->tmf_state = TMF_INITIAL; |
| 1904 | spin_unlock(&session->lock); | 1913 | spin_unlock(&session->lock); |
| 1905 | iscsi_start_tx(conn); | 1914 | iscsi_start_tx(conn); |
| @@ -2572,7 +2581,7 @@ static void | |||
| 2572 | fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) | 2581 | fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) |
| 2573 | { | 2582 | { |
| 2574 | struct iscsi_task *task; | 2583 | struct iscsi_task *task; |
| 2575 | int i; | 2584 | int i, state; |
| 2576 | 2585 | ||
| 2577 | for (i = 0; i < conn->session->cmds_max; i++) { | 2586 | for (i = 0; i < conn->session->cmds_max; i++) { |
| 2578 | task = conn->session->cmds[i]; | 2587 | task = conn->session->cmds[i]; |
| @@ -2585,7 +2594,11 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) | |||
| 2585 | ISCSI_DBG_SESSION(conn->session, | 2594 | ISCSI_DBG_SESSION(conn->session, |
| 2586 | "failing mgmt itt 0x%x state %d\n", | 2595 | "failing mgmt itt 0x%x state %d\n", |
| 2587 | task->itt, task->state); | 2596 | task->itt, task->state); |
| 2588 | iscsi_complete_task(task); | 2597 | state = ISCSI_TASK_ABRT_SESS_RECOV; |
| 2598 | if (task->state == ISCSI_TASK_PENDING) | ||
| 2599 | state = ISCSI_TASK_COMPLETED; | ||
| 2600 | iscsi_complete_task(task, state); | ||
| 2601 | |||
| 2589 | } | 2602 | } |
| 2590 | } | 2603 | } |
| 2591 | 2604 | ||
| @@ -2642,10 +2655,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
| 2642 | * flush queues. | 2655 | * flush queues. |
| 2643 | */ | 2656 | */ |
| 2644 | spin_lock_bh(&session->lock); | 2657 | spin_lock_bh(&session->lock); |
| 2645 | if (flag == STOP_CONN_RECOVER) | 2658 | fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED); |
| 2646 | fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED); | ||
| 2647 | else | ||
| 2648 | fail_scsi_tasks(conn, -1, DID_ERROR); | ||
| 2649 | fail_mgmt_tasks(session, conn); | 2659 | fail_mgmt_tasks(session, conn); |
| 2650 | spin_unlock_bh(&session->lock); | 2660 | spin_unlock_bh(&session->lock); |
| 2651 | mutex_unlock(&session->eh_mutex); | 2661 | mutex_unlock(&session->eh_mutex); |
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index b84a1d853f29..2bc07090321d 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c | |||
| @@ -440,8 +440,8 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task) | |||
| 440 | struct iscsi_tcp_task *tcp_task = task->dd_data; | 440 | struct iscsi_tcp_task *tcp_task = task->dd_data; |
| 441 | struct iscsi_r2t_info *r2t; | 441 | struct iscsi_r2t_info *r2t; |
| 442 | 442 | ||
| 443 | /* nothing to do for mgmt or pending tasks */ | 443 | /* nothing to do for mgmt */ |
| 444 | if (!task->sc || task->state == ISCSI_TASK_PENDING) | 444 | if (!task->sc) |
| 445 | return; | 445 | return; |
| 446 | 446 | ||
| 447 | /* flush task's r2t queues */ | 447 | /* flush task's r2t queues */ |
