diff options
author | Andy Grover <agrover@redhat.com> | 2012-04-03 18:51:09 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-04-14 20:40:34 -0400 |
commit | 6f3c0e69a9c20441bdc6d3b2d18b83b244384ec6 (patch) | |
tree | c974a5838d4b117acee40eeeb00b786cb2e0db21 /drivers/target/iscsi | |
parent | 4580cf38483790a4304a15328303566a054d4ea5 (diff) |
target/iscsi: Refactor target_tx_thread immediate+response queue loops
Immediate queue:
Consolidate down to one switch statement by moving send_tx_data and stuff
from second switch into the first switch, or the functions the first switch
calls.
Response queue:
Do not lock istate_lock except directly around i_state modifications.
Put entire ISTATE_SEND_DATAIN path within first switch statement, in prep
for further refactoring.
All other cases set use_misc = 1 and will not be using sendpage, so just
use send_tx_data for these and set use_misc param to 1.
map_sg, sent_status, use_misc, and se_cmd vars no longer needed.
Then put immediate and response handling in separate functions in order
to get iscsi_target_tx_thread down to where it fits on a page.
Signed-off-by: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/iscsi')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 487 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.h | 1 |
2 files changed, 244 insertions, 244 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 8428fa51beed..fd2b6381cb48 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -2434,10 +2434,19 @@ static int iscsit_send_conn_drop_async_message( | |||
2434 | return 0; | 2434 | return 0; |
2435 | } | 2435 | } |
2436 | 2436 | ||
2437 | static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) | ||
2438 | { | ||
2439 | if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || | ||
2440 | (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { | ||
2441 | wait_for_completion_interruptible_timeout( | ||
2442 | &conn->tx_half_close_comp, | ||
2443 | ISCSI_TX_THREAD_TCP_TIMEOUT * HZ); | ||
2444 | } | ||
2445 | } | ||
2446 | |||
2437 | static int iscsit_send_data_in( | 2447 | static int iscsit_send_data_in( |
2438 | struct iscsi_cmd *cmd, | 2448 | struct iscsi_cmd *cmd, |
2439 | struct iscsi_conn *conn, | 2449 | struct iscsi_conn *conn) |
2440 | int *eodr) | ||
2441 | { | 2450 | { |
2442 | int iov_ret = 0, set_statsn = 0; | 2451 | int iov_ret = 0, set_statsn = 0; |
2443 | u32 iov_count = 0, tx_size = 0; | 2452 | u32 iov_count = 0, tx_size = 0; |
@@ -2445,6 +2454,8 @@ static int iscsit_send_data_in( | |||
2445 | struct iscsi_datain_req *dr; | 2454 | struct iscsi_datain_req *dr; |
2446 | struct iscsi_data_rsp *hdr; | 2455 | struct iscsi_data_rsp *hdr; |
2447 | struct kvec *iov; | 2456 | struct kvec *iov; |
2457 | int eodr = 0; | ||
2458 | int ret; | ||
2448 | 2459 | ||
2449 | memset(&datain, 0, sizeof(struct iscsi_datain)); | 2460 | memset(&datain, 0, sizeof(struct iscsi_datain)); |
2450 | dr = iscsit_get_datain_values(cmd, &datain); | 2461 | dr = iscsit_get_datain_values(cmd, &datain); |
@@ -2577,13 +2588,26 @@ static int iscsit_send_data_in( | |||
2577 | cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn), | 2588 | cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn), |
2578 | ntohl(hdr->offset), datain.length, conn->cid); | 2589 | ntohl(hdr->offset), datain.length, conn->cid); |
2579 | 2590 | ||
2591 | /* sendpage is preferred but can't insert markers */ | ||
2592 | if (!conn->conn_ops->IFMarker) | ||
2593 | ret = iscsit_fe_sendpage_sg(cmd, conn); | ||
2594 | else | ||
2595 | ret = iscsit_send_tx_data(cmd, conn, 0); | ||
2596 | |||
2597 | iscsit_unmap_iovec(cmd); | ||
2598 | |||
2599 | if (ret < 0) { | ||
2600 | iscsit_tx_thread_wait_for_tcp(conn); | ||
2601 | return ret; | ||
2602 | } | ||
2603 | |||
2580 | if (dr->dr_complete) { | 2604 | if (dr->dr_complete) { |
2581 | *eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ? | 2605 | eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ? |
2582 | 2 : 1; | 2606 | 2 : 1; |
2583 | iscsit_free_datain_req(cmd, dr); | 2607 | iscsit_free_datain_req(cmd, dr); |
2584 | } | 2608 | } |
2585 | 2609 | ||
2586 | return 0; | 2610 | return eodr; |
2587 | } | 2611 | } |
2588 | 2612 | ||
2589 | static int iscsit_send_logout_response( | 2613 | static int iscsit_send_logout_response( |
@@ -2715,6 +2739,7 @@ static int iscsit_send_unsolicited_nopin( | |||
2715 | { | 2739 | { |
2716 | int tx_size = ISCSI_HDR_LEN; | 2740 | int tx_size = ISCSI_HDR_LEN; |
2717 | struct iscsi_nopin *hdr; | 2741 | struct iscsi_nopin *hdr; |
2742 | int ret; | ||
2718 | 2743 | ||
2719 | hdr = (struct iscsi_nopin *) cmd->pdu; | 2744 | hdr = (struct iscsi_nopin *) cmd->pdu; |
2720 | memset(hdr, 0, ISCSI_HDR_LEN); | 2745 | memset(hdr, 0, ISCSI_HDR_LEN); |
@@ -2747,6 +2772,17 @@ static int iscsit_send_unsolicited_nopin( | |||
2747 | pr_debug("Sending Unsolicited NOPIN TTT: 0x%08x StatSN:" | 2772 | pr_debug("Sending Unsolicited NOPIN TTT: 0x%08x StatSN:" |
2748 | " 0x%08x CID: %hu\n", hdr->ttt, cmd->stat_sn, conn->cid); | 2773 | " 0x%08x CID: %hu\n", hdr->ttt, cmd->stat_sn, conn->cid); |
2749 | 2774 | ||
2775 | ret = iscsit_send_tx_data(cmd, conn, 1); | ||
2776 | if (ret < 0) { | ||
2777 | iscsit_tx_thread_wait_for_tcp(conn); | ||
2778 | return ret; | ||
2779 | } | ||
2780 | |||
2781 | spin_lock_bh(&cmd->istate_lock); | ||
2782 | cmd->i_state = want_response ? | ||
2783 | ISTATE_SENT_NOPIN_WANT_RESPONSE : ISTATE_SENT_STATUS; | ||
2784 | spin_unlock_bh(&cmd->istate_lock); | ||
2785 | |||
2750 | return 0; | 2786 | return 0; |
2751 | } | 2787 | } |
2752 | 2788 | ||
@@ -2837,13 +2873,14 @@ static int iscsit_send_nopin_response( | |||
2837 | return 0; | 2873 | return 0; |
2838 | } | 2874 | } |
2839 | 2875 | ||
2840 | int iscsit_send_r2t( | 2876 | static int iscsit_send_r2t( |
2841 | struct iscsi_cmd *cmd, | 2877 | struct iscsi_cmd *cmd, |
2842 | struct iscsi_conn *conn) | 2878 | struct iscsi_conn *conn) |
2843 | { | 2879 | { |
2844 | int tx_size = 0; | 2880 | int tx_size = 0; |
2845 | struct iscsi_r2t *r2t; | 2881 | struct iscsi_r2t *r2t; |
2846 | struct iscsi_r2t_rsp *hdr; | 2882 | struct iscsi_r2t_rsp *hdr; |
2883 | int ret; | ||
2847 | 2884 | ||
2848 | r2t = iscsit_get_r2t_from_list(cmd); | 2885 | r2t = iscsit_get_r2t_from_list(cmd); |
2849 | if (!r2t) | 2886 | if (!r2t) |
@@ -2899,6 +2936,16 @@ int iscsit_send_r2t( | |||
2899 | r2t->sent_r2t = 1; | 2936 | r2t->sent_r2t = 1; |
2900 | spin_unlock_bh(&cmd->r2t_lock); | 2937 | spin_unlock_bh(&cmd->r2t_lock); |
2901 | 2938 | ||
2939 | ret = iscsit_send_tx_data(cmd, conn, 1); | ||
2940 | if (ret < 0) { | ||
2941 | iscsit_tx_thread_wait_for_tcp(conn); | ||
2942 | return ret; | ||
2943 | } | ||
2944 | |||
2945 | spin_lock_bh(&cmd->dataout_timeout_lock); | ||
2946 | iscsit_start_dataout_timer(cmd, conn); | ||
2947 | spin_unlock_bh(&cmd->dataout_timeout_lock); | ||
2948 | |||
2902 | return 0; | 2949 | return 0; |
2903 | } | 2950 | } |
2904 | 2951 | ||
@@ -3407,16 +3454,6 @@ static int iscsit_send_reject( | |||
3407 | return 0; | 3454 | return 0; |
3408 | } | 3455 | } |
3409 | 3456 | ||
3410 | static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) | ||
3411 | { | ||
3412 | if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || | ||
3413 | (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { | ||
3414 | wait_for_completion_interruptible_timeout( | ||
3415 | &conn->tx_half_close_comp, | ||
3416 | ISCSI_TX_THREAD_TCP_TIMEOUT * HZ); | ||
3417 | } | ||
3418 | } | ||
3419 | |||
3420 | void iscsit_thread_get_cpumask(struct iscsi_conn *conn) | 3457 | void iscsit_thread_get_cpumask(struct iscsi_conn *conn) |
3421 | { | 3458 | { |
3422 | struct iscsi_thread_set *ts = conn->thread_set; | 3459 | struct iscsi_thread_set *ts = conn->thread_set; |
@@ -3472,17 +3509,193 @@ static inline void iscsit_thread_check_cpumask( | |||
3472 | set_cpus_allowed_ptr(p, conn->conn_cpumask); | 3509 | set_cpus_allowed_ptr(p, conn->conn_cpumask); |
3473 | } | 3510 | } |
3474 | 3511 | ||
3475 | int iscsi_target_tx_thread(void *arg) | 3512 | static int handle_immediate_queue(struct iscsi_conn *conn) |
3476 | { | 3513 | { |
3514 | struct iscsi_queue_req *qr; | ||
3515 | struct iscsi_cmd *cmd; | ||
3477 | u8 state; | 3516 | u8 state; |
3478 | int eodr = 0; | 3517 | int ret; |
3518 | |||
3519 | while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) { | ||
3520 | atomic_set(&conn->check_immediate_queue, 0); | ||
3521 | cmd = qr->cmd; | ||
3522 | state = qr->state; | ||
3523 | kmem_cache_free(lio_qr_cache, qr); | ||
3524 | |||
3525 | switch (state) { | ||
3526 | case ISTATE_SEND_R2T: | ||
3527 | ret = iscsit_send_r2t(cmd, conn); | ||
3528 | if (ret < 0) | ||
3529 | goto err; | ||
3530 | break; | ||
3531 | case ISTATE_REMOVE: | ||
3532 | if (cmd->data_direction == DMA_TO_DEVICE) | ||
3533 | iscsit_stop_dataout_timer(cmd); | ||
3534 | |||
3535 | spin_lock_bh(&conn->cmd_lock); | ||
3536 | list_del(&cmd->i_conn_node); | ||
3537 | spin_unlock_bh(&conn->cmd_lock); | ||
3538 | |||
3539 | iscsit_free_cmd(cmd); | ||
3540 | continue; | ||
3541 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: | ||
3542 | iscsit_mod_nopin_response_timer(conn); | ||
3543 | ret = iscsit_send_unsolicited_nopin(cmd, | ||
3544 | conn, 1); | ||
3545 | if (ret < 0) | ||
3546 | goto err; | ||
3547 | break; | ||
3548 | case ISTATE_SEND_NOPIN_NO_RESPONSE: | ||
3549 | ret = iscsit_send_unsolicited_nopin(cmd, | ||
3550 | conn, 0); | ||
3551 | if (ret < 0) | ||
3552 | goto err; | ||
3553 | break; | ||
3554 | default: | ||
3555 | pr_err("Unknown Opcode: 0x%02x ITT:" | ||
3556 | " 0x%08x, i_state: %d on CID: %hu\n", | ||
3557 | cmd->iscsi_opcode, cmd->init_task_tag, state, | ||
3558 | conn->cid); | ||
3559 | goto err; | ||
3560 | } | ||
3561 | } | ||
3562 | |||
3563 | return 0; | ||
3564 | |||
3565 | err: | ||
3566 | return -1; | ||
3567 | } | ||
3568 | |||
3569 | static int handle_response_queue(struct iscsi_conn *conn) | ||
3570 | { | ||
3571 | struct iscsi_queue_req *qr; | ||
3572 | struct iscsi_cmd *cmd; | ||
3573 | u8 state; | ||
3574 | int ret; | ||
3575 | |||
3576 | while ((qr = iscsit_get_cmd_from_response_queue(conn))) { | ||
3577 | cmd = qr->cmd; | ||
3578 | state = qr->state; | ||
3579 | kmem_cache_free(lio_qr_cache, qr); | ||
3580 | |||
3581 | check_rsp_state: | ||
3582 | switch (state) { | ||
3583 | case ISTATE_SEND_DATAIN: | ||
3584 | ret = iscsit_send_data_in(cmd, conn); | ||
3585 | if (ret < 0) | ||
3586 | goto err; | ||
3587 | else if (!ret) | ||
3588 | /* more drs */ | ||
3589 | goto check_rsp_state; | ||
3590 | else if (ret == 1) { | ||
3591 | /* all done */ | ||
3592 | spin_lock_bh(&cmd->istate_lock); | ||
3593 | cmd->i_state = ISTATE_SENT_STATUS; | ||
3594 | spin_unlock_bh(&cmd->istate_lock); | ||
3595 | continue; | ||
3596 | } else if (ret == 2) { | ||
3597 | /* Still must send status, | ||
3598 | SCF_TRANSPORT_TASK_SENSE was set */ | ||
3599 | spin_lock_bh(&cmd->istate_lock); | ||
3600 | cmd->i_state = ISTATE_SEND_STATUS; | ||
3601 | spin_unlock_bh(&cmd->istate_lock); | ||
3602 | state = ISTATE_SEND_STATUS; | ||
3603 | goto check_rsp_state; | ||
3604 | } | ||
3605 | |||
3606 | break; | ||
3607 | case ISTATE_SEND_STATUS: | ||
3608 | case ISTATE_SEND_STATUS_RECOVERY: | ||
3609 | ret = iscsit_send_status(cmd, conn); | ||
3610 | break; | ||
3611 | case ISTATE_SEND_LOGOUTRSP: | ||
3612 | ret = iscsit_send_logout_response(cmd, conn); | ||
3613 | break; | ||
3614 | case ISTATE_SEND_ASYNCMSG: | ||
3615 | ret = iscsit_send_conn_drop_async_message( | ||
3616 | cmd, conn); | ||
3617 | break; | ||
3618 | case ISTATE_SEND_NOPIN: | ||
3619 | ret = iscsit_send_nopin_response(cmd, conn); | ||
3620 | break; | ||
3621 | case ISTATE_SEND_REJECT: | ||
3622 | ret = iscsit_send_reject(cmd, conn); | ||
3623 | break; | ||
3624 | case ISTATE_SEND_TASKMGTRSP: | ||
3625 | ret = iscsit_send_task_mgt_rsp(cmd, conn); | ||
3626 | if (ret != 0) | ||
3627 | break; | ||
3628 | ret = iscsit_tmr_post_handler(cmd, conn); | ||
3629 | if (ret != 0) | ||
3630 | iscsit_fall_back_to_erl0(conn->sess); | ||
3631 | break; | ||
3632 | case ISTATE_SEND_TEXTRSP: | ||
3633 | ret = iscsit_send_text_rsp(cmd, conn); | ||
3634 | break; | ||
3635 | default: | ||
3636 | pr_err("Unknown Opcode: 0x%02x ITT:" | ||
3637 | " 0x%08x, i_state: %d on CID: %hu\n", | ||
3638 | cmd->iscsi_opcode, cmd->init_task_tag, | ||
3639 | state, conn->cid); | ||
3640 | goto err; | ||
3641 | } | ||
3642 | if (ret < 0) | ||
3643 | goto err; | ||
3644 | |||
3645 | if (iscsit_send_tx_data(cmd, conn, 1) < 0) { | ||
3646 | iscsit_tx_thread_wait_for_tcp(conn); | ||
3647 | iscsit_unmap_iovec(cmd); | ||
3648 | goto err; | ||
3649 | } | ||
3650 | iscsit_unmap_iovec(cmd); | ||
3651 | |||
3652 | switch (state) { | ||
3653 | case ISTATE_SEND_LOGOUTRSP: | ||
3654 | if (!iscsit_logout_post_handler(cmd, conn)) | ||
3655 | goto restart; | ||
3656 | /* fall through */ | ||
3657 | case ISTATE_SEND_STATUS: | ||
3658 | case ISTATE_SEND_ASYNCMSG: | ||
3659 | case ISTATE_SEND_NOPIN: | ||
3660 | case ISTATE_SEND_STATUS_RECOVERY: | ||
3661 | case ISTATE_SEND_TEXTRSP: | ||
3662 | case ISTATE_SEND_TASKMGTRSP: | ||
3663 | spin_lock_bh(&cmd->istate_lock); | ||
3664 | cmd->i_state = ISTATE_SENT_STATUS; | ||
3665 | spin_unlock_bh(&cmd->istate_lock); | ||
3666 | break; | ||
3667 | case ISTATE_SEND_REJECT: | ||
3668 | if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { | ||
3669 | cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; | ||
3670 | complete(&cmd->reject_comp); | ||
3671 | goto err; | ||
3672 | } | ||
3673 | complete(&cmd->reject_comp); | ||
3674 | break; | ||
3675 | default: | ||
3676 | pr_err("Unknown Opcode: 0x%02x ITT:" | ||
3677 | " 0x%08x, i_state: %d on CID: %hu\n", | ||
3678 | cmd->iscsi_opcode, cmd->init_task_tag, | ||
3679 | cmd->i_state, conn->cid); | ||
3680 | goto err; | ||
3681 | } | ||
3682 | |||
3683 | if (atomic_read(&conn->check_immediate_queue)) | ||
3684 | break; | ||
3685 | } | ||
3686 | |||
3687 | return 0; | ||
3688 | |||
3689 | err: | ||
3690 | return -1; | ||
3691 | restart: | ||
3692 | return -EAGAIN; | ||
3693 | } | ||
3694 | |||
3695 | int iscsi_target_tx_thread(void *arg) | ||
3696 | { | ||
3479 | int ret = 0; | 3697 | int ret = 0; |
3480 | int sent_status = 0; | ||
3481 | int use_misc = 0; | ||
3482 | int map_sg = 0; | ||
3483 | struct iscsi_cmd *cmd = NULL; | ||
3484 | struct iscsi_conn *conn; | 3698 | struct iscsi_conn *conn; |
3485 | struct iscsi_queue_req *qr = NULL; | ||
3486 | struct iscsi_thread_set *ts = arg; | 3699 | struct iscsi_thread_set *ts = arg; |
3487 | /* | 3700 | /* |
3488 | * Allow ourselves to be interrupted by SIGINT so that a | 3701 | * Allow ourselves to be interrupted by SIGINT so that a |
@@ -3495,7 +3708,7 @@ restart: | |||
3495 | if (!conn) | 3708 | if (!conn) |
3496 | goto out; | 3709 | goto out; |
3497 | 3710 | ||
3498 | eodr = map_sg = ret = sent_status = use_misc = 0; | 3711 | ret = 0; |
3499 | 3712 | ||
3500 | while (!kthread_should_stop()) { | 3713 | while (!kthread_should_stop()) { |
3501 | /* | 3714 | /* |
@@ -3510,227 +3723,15 @@ restart: | |||
3510 | signal_pending(current)) | 3723 | signal_pending(current)) |
3511 | goto transport_err; | 3724 | goto transport_err; |
3512 | 3725 | ||
3513 | while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) { | 3726 | ret = handle_immediate_queue(conn); |
3514 | atomic_set(&conn->check_immediate_queue, 0); | 3727 | if (ret < 0) |
3515 | cmd = qr->cmd; | 3728 | goto transport_err; |
3516 | state = qr->state; | ||
3517 | kmem_cache_free(lio_qr_cache, qr); | ||
3518 | |||
3519 | switch (state) { | ||
3520 | case ISTATE_SEND_R2T: | ||
3521 | ret = iscsit_send_r2t(cmd, conn); | ||
3522 | break; | ||
3523 | case ISTATE_REMOVE: | ||
3524 | if (cmd->data_direction == DMA_TO_DEVICE) | ||
3525 | iscsit_stop_dataout_timer(cmd); | ||
3526 | |||
3527 | spin_lock_bh(&conn->cmd_lock); | ||
3528 | list_del(&cmd->i_conn_node); | ||
3529 | spin_unlock_bh(&conn->cmd_lock); | ||
3530 | |||
3531 | iscsit_free_cmd(cmd); | ||
3532 | continue; | ||
3533 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: | ||
3534 | iscsit_mod_nopin_response_timer(conn); | ||
3535 | ret = iscsit_send_unsolicited_nopin(cmd, | ||
3536 | conn, 1); | ||
3537 | break; | ||
3538 | case ISTATE_SEND_NOPIN_NO_RESPONSE: | ||
3539 | ret = iscsit_send_unsolicited_nopin(cmd, | ||
3540 | conn, 0); | ||
3541 | break; | ||
3542 | default: | ||
3543 | pr_err("Unknown Opcode: 0x%02x ITT:" | ||
3544 | " 0x%08x, i_state: %d on CID: %hu\n", | ||
3545 | cmd->iscsi_opcode, cmd->init_task_tag, state, | ||
3546 | conn->cid); | ||
3547 | goto transport_err; | ||
3548 | } | ||
3549 | if (ret < 0) | ||
3550 | goto transport_err; | ||
3551 | |||
3552 | if (iscsit_send_tx_data(cmd, conn, 1) < 0) { | ||
3553 | iscsit_tx_thread_wait_for_tcp(conn); | ||
3554 | goto transport_err; | ||
3555 | } | ||
3556 | |||
3557 | switch (state) { | ||
3558 | case ISTATE_SEND_R2T: | ||
3559 | spin_lock_bh(&cmd->dataout_timeout_lock); | ||
3560 | iscsit_start_dataout_timer(cmd, conn); | ||
3561 | spin_unlock_bh(&cmd->dataout_timeout_lock); | ||
3562 | break; | ||
3563 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: | ||
3564 | spin_lock_bh(&cmd->istate_lock); | ||
3565 | cmd->i_state = ISTATE_SENT_NOPIN_WANT_RESPONSE; | ||
3566 | spin_unlock_bh(&cmd->istate_lock); | ||
3567 | break; | ||
3568 | case ISTATE_SEND_NOPIN_NO_RESPONSE: | ||
3569 | spin_lock_bh(&cmd->istate_lock); | ||
3570 | cmd->i_state = ISTATE_SENT_STATUS; | ||
3571 | spin_unlock_bh(&cmd->istate_lock); | ||
3572 | break; | ||
3573 | default: | ||
3574 | pr_err("Unknown Opcode: 0x%02x ITT:" | ||
3575 | " 0x%08x, i_state: %d on CID: %hu\n", | ||
3576 | cmd->iscsi_opcode, cmd->init_task_tag, | ||
3577 | state, conn->cid); | ||
3578 | goto transport_err; | ||
3579 | } | ||
3580 | } | ||
3581 | |||
3582 | while ((qr = iscsit_get_cmd_from_response_queue(conn))) { | ||
3583 | cmd = qr->cmd; | ||
3584 | state = qr->state; | ||
3585 | kmem_cache_free(lio_qr_cache, qr); | ||
3586 | |||
3587 | spin_lock_bh(&cmd->istate_lock); | ||
3588 | check_rsp_state: | ||
3589 | switch (state) { | ||
3590 | case ISTATE_SEND_DATAIN: | ||
3591 | spin_unlock_bh(&cmd->istate_lock); | ||
3592 | ret = iscsit_send_data_in(cmd, conn, | ||
3593 | &eodr); | ||
3594 | map_sg = 1; | ||
3595 | break; | ||
3596 | case ISTATE_SEND_STATUS: | ||
3597 | case ISTATE_SEND_STATUS_RECOVERY: | ||
3598 | spin_unlock_bh(&cmd->istate_lock); | ||
3599 | use_misc = 1; | ||
3600 | ret = iscsit_send_status(cmd, conn); | ||
3601 | break; | ||
3602 | case ISTATE_SEND_LOGOUTRSP: | ||
3603 | spin_unlock_bh(&cmd->istate_lock); | ||
3604 | use_misc = 1; | ||
3605 | ret = iscsit_send_logout_response(cmd, conn); | ||
3606 | break; | ||
3607 | case ISTATE_SEND_ASYNCMSG: | ||
3608 | spin_unlock_bh(&cmd->istate_lock); | ||
3609 | use_misc = 1; | ||
3610 | ret = iscsit_send_conn_drop_async_message( | ||
3611 | cmd, conn); | ||
3612 | break; | ||
3613 | case ISTATE_SEND_NOPIN: | ||
3614 | spin_unlock_bh(&cmd->istate_lock); | ||
3615 | use_misc = 1; | ||
3616 | ret = iscsit_send_nopin_response(cmd, conn); | ||
3617 | break; | ||
3618 | case ISTATE_SEND_REJECT: | ||
3619 | spin_unlock_bh(&cmd->istate_lock); | ||
3620 | use_misc = 1; | ||
3621 | ret = iscsit_send_reject(cmd, conn); | ||
3622 | break; | ||
3623 | case ISTATE_SEND_TASKMGTRSP: | ||
3624 | spin_unlock_bh(&cmd->istate_lock); | ||
3625 | use_misc = 1; | ||
3626 | ret = iscsit_send_task_mgt_rsp(cmd, conn); | ||
3627 | if (ret != 0) | ||
3628 | break; | ||
3629 | ret = iscsit_tmr_post_handler(cmd, conn); | ||
3630 | if (ret != 0) | ||
3631 | iscsit_fall_back_to_erl0(conn->sess); | ||
3632 | break; | ||
3633 | case ISTATE_SEND_TEXTRSP: | ||
3634 | spin_unlock_bh(&cmd->istate_lock); | ||
3635 | use_misc = 1; | ||
3636 | ret = iscsit_send_text_rsp(cmd, conn); | ||
3637 | break; | ||
3638 | default: | ||
3639 | pr_err("Unknown Opcode: 0x%02x ITT:" | ||
3640 | " 0x%08x, i_state: %d on CID: %hu\n", | ||
3641 | cmd->iscsi_opcode, cmd->init_task_tag, | ||
3642 | state, conn->cid); | ||
3643 | spin_unlock_bh(&cmd->istate_lock); | ||
3644 | goto transport_err; | ||
3645 | } | ||
3646 | if (ret < 0) | ||
3647 | goto transport_err; | ||
3648 | |||
3649 | if (map_sg && !conn->conn_ops->IFMarker) { | ||
3650 | if (iscsit_fe_sendpage_sg(cmd, conn) < 0) { | ||
3651 | iscsit_tx_thread_wait_for_tcp(conn); | ||
3652 | iscsit_unmap_iovec(cmd); | ||
3653 | goto transport_err; | ||
3654 | } | ||
3655 | } else { | ||
3656 | if (iscsit_send_tx_data(cmd, conn, use_misc) < 0) { | ||
3657 | iscsit_tx_thread_wait_for_tcp(conn); | ||
3658 | iscsit_unmap_iovec(cmd); | ||
3659 | goto transport_err; | ||
3660 | } | ||
3661 | } | ||
3662 | map_sg = 0; | ||
3663 | iscsit_unmap_iovec(cmd); | ||
3664 | |||
3665 | spin_lock_bh(&cmd->istate_lock); | ||
3666 | switch (state) { | ||
3667 | case ISTATE_SEND_DATAIN: | ||
3668 | if (!eodr) | ||
3669 | goto check_rsp_state; | ||
3670 | |||
3671 | if (eodr == 1) { | ||
3672 | cmd->i_state = ISTATE_SENT_LAST_DATAIN; | ||
3673 | sent_status = 1; | ||
3674 | eodr = use_misc = 0; | ||
3675 | } else if (eodr == 2) { | ||
3676 | cmd->i_state = state = | ||
3677 | ISTATE_SEND_STATUS; | ||
3678 | sent_status = 0; | ||
3679 | eodr = use_misc = 0; | ||
3680 | goto check_rsp_state; | ||
3681 | } | ||
3682 | break; | ||
3683 | case ISTATE_SEND_STATUS: | ||
3684 | use_misc = 0; | ||
3685 | sent_status = 1; | ||
3686 | break; | ||
3687 | case ISTATE_SEND_ASYNCMSG: | ||
3688 | case ISTATE_SEND_NOPIN: | ||
3689 | case ISTATE_SEND_STATUS_RECOVERY: | ||
3690 | case ISTATE_SEND_TEXTRSP: | ||
3691 | use_misc = 0; | ||
3692 | sent_status = 1; | ||
3693 | break; | ||
3694 | case ISTATE_SEND_REJECT: | ||
3695 | use_misc = 0; | ||
3696 | if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { | ||
3697 | cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; | ||
3698 | spin_unlock_bh(&cmd->istate_lock); | ||
3699 | complete(&cmd->reject_comp); | ||
3700 | goto transport_err; | ||
3701 | } | ||
3702 | complete(&cmd->reject_comp); | ||
3703 | break; | ||
3704 | case ISTATE_SEND_TASKMGTRSP: | ||
3705 | use_misc = 0; | ||
3706 | sent_status = 1; | ||
3707 | break; | ||
3708 | case ISTATE_SEND_LOGOUTRSP: | ||
3709 | spin_unlock_bh(&cmd->istate_lock); | ||
3710 | if (!iscsit_logout_post_handler(cmd, conn)) | ||
3711 | goto restart; | ||
3712 | spin_lock_bh(&cmd->istate_lock); | ||
3713 | use_misc = 0; | ||
3714 | sent_status = 1; | ||
3715 | break; | ||
3716 | default: | ||
3717 | pr_err("Unknown Opcode: 0x%02x ITT:" | ||
3718 | " 0x%08x, i_state: %d on CID: %hu\n", | ||
3719 | cmd->iscsi_opcode, cmd->init_task_tag, | ||
3720 | cmd->i_state, conn->cid); | ||
3721 | spin_unlock_bh(&cmd->istate_lock); | ||
3722 | goto transport_err; | ||
3723 | } | ||
3724 | |||
3725 | if (sent_status) { | ||
3726 | cmd->i_state = ISTATE_SENT_STATUS; | ||
3727 | sent_status = 0; | ||
3728 | } | ||
3729 | spin_unlock_bh(&cmd->istate_lock); | ||
3730 | 3729 | ||
3731 | if (atomic_read(&conn->check_immediate_queue)) | 3730 | ret = handle_response_queue(conn); |
3732 | break; | 3731 | if (ret == -EAGAIN) |
3733 | } | 3732 | goto restart; |
3733 | else if (ret < 0) | ||
3734 | goto transport_err; | ||
3734 | } | 3735 | } |
3735 | 3736 | ||
3736 | transport_err: | 3737 | transport_err: |
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index 5db2ddeed5eb..7934cdc91356 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h | |||
@@ -18,7 +18,6 @@ extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); | |||
18 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); | 18 | extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); |
19 | extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *); | 19 | extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *); |
20 | extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8); | 20 | extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8); |
21 | extern int iscsit_send_r2t(struct iscsi_cmd *, struct iscsi_conn *); | ||
22 | extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, int); | 21 | extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, int); |
23 | extern void iscsit_thread_get_cpumask(struct iscsi_conn *); | 22 | extern void iscsit_thread_get_cpumask(struct iscsi_conn *); |
24 | extern int iscsi_target_tx_thread(void *); | 23 | extern int iscsi_target_tx_thread(void *); |