diff options
Diffstat (limited to 'drivers/target')
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 12 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_erl2.c | 12 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_parameters.c | 8 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_parameters.h | 4 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 50 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_util.h | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_file.c | 11 | ||||
| -rw-r--r-- | drivers/target/target_core_transport.c | 74 |
8 files changed, 96 insertions, 77 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 262ef1f23b38..d7705e5824fb 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -651,7 +651,7 @@ static int iscsit_add_reject( | |||
| 651 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 651 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
| 652 | if (!cmd->buf_ptr) { | 652 | if (!cmd->buf_ptr) { |
| 653 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 653 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
| 654 | iscsit_release_cmd(cmd); | 654 | iscsit_free_cmd(cmd, false); |
| 655 | return -1; | 655 | return -1; |
| 656 | } | 656 | } |
| 657 | 657 | ||
| @@ -697,7 +697,7 @@ int iscsit_add_reject_from_cmd( | |||
| 697 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); | 697 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
| 698 | if (!cmd->buf_ptr) { | 698 | if (!cmd->buf_ptr) { |
| 699 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 699 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
| 700 | iscsit_release_cmd(cmd); | 700 | iscsit_free_cmd(cmd, false); |
| 701 | return -1; | 701 | return -1; |
| 702 | } | 702 | } |
| 703 | 703 | ||
| @@ -1743,7 +1743,7 @@ int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 1743 | return 0; | 1743 | return 0; |
| 1744 | out: | 1744 | out: |
| 1745 | if (cmd) | 1745 | if (cmd) |
| 1746 | iscsit_release_cmd(cmd); | 1746 | iscsit_free_cmd(cmd, false); |
| 1747 | ping_out: | 1747 | ping_out: |
| 1748 | kfree(ping_data); | 1748 | kfree(ping_data); |
| 1749 | return ret; | 1749 | return ret; |
| @@ -2251,7 +2251,7 @@ iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
| 2251 | if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { | 2251 | if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { |
| 2252 | pr_err("Received logout request on connection that" | 2252 | pr_err("Received logout request on connection that" |
| 2253 | " is not in logged in state, ignoring request.\n"); | 2253 | " is not in logged in state, ignoring request.\n"); |
| 2254 | iscsit_release_cmd(cmd); | 2254 | iscsit_free_cmd(cmd, false); |
| 2255 | return 0; | 2255 | return 0; |
| 2256 | } | 2256 | } |
| 2257 | 2257 | ||
| @@ -3665,7 +3665,7 @@ iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state | |||
| 3665 | list_del(&cmd->i_conn_node); | 3665 | list_del(&cmd->i_conn_node); |
| 3666 | spin_unlock_bh(&conn->cmd_lock); | 3666 | spin_unlock_bh(&conn->cmd_lock); |
| 3667 | 3667 | ||
| 3668 | iscsit_free_cmd(cmd); | 3668 | iscsit_free_cmd(cmd, false); |
| 3669 | break; | 3669 | break; |
| 3670 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: | 3670 | case ISTATE_SEND_NOPIN_WANT_RESPONSE: |
| 3671 | iscsit_mod_nopin_response_timer(conn); | 3671 | iscsit_mod_nopin_response_timer(conn); |
| @@ -4122,7 +4122,7 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) | |||
| 4122 | 4122 | ||
| 4123 | iscsit_increment_maxcmdsn(cmd, sess); | 4123 | iscsit_increment_maxcmdsn(cmd, sess); |
| 4124 | 4124 | ||
| 4125 | iscsit_free_cmd(cmd); | 4125 | iscsit_free_cmd(cmd, true); |
| 4126 | 4126 | ||
| 4127 | spin_lock_bh(&conn->cmd_lock); | 4127 | spin_lock_bh(&conn->cmd_lock); |
| 4128 | } | 4128 | } |
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index ba6091bf93fc..45a5afd5ea13 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c | |||
| @@ -143,7 +143,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
| 143 | list_del(&cmd->i_conn_node); | 143 | list_del(&cmd->i_conn_node); |
| 144 | cmd->conn = NULL; | 144 | cmd->conn = NULL; |
| 145 | spin_unlock(&cr->conn_recovery_cmd_lock); | 145 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| 146 | iscsit_free_cmd(cmd); | 146 | iscsit_free_cmd(cmd, true); |
| 147 | spin_lock(&cr->conn_recovery_cmd_lock); | 147 | spin_lock(&cr->conn_recovery_cmd_lock); |
| 148 | } | 148 | } |
| 149 | spin_unlock(&cr->conn_recovery_cmd_lock); | 149 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| @@ -165,7 +165,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
| 165 | list_del(&cmd->i_conn_node); | 165 | list_del(&cmd->i_conn_node); |
| 166 | cmd->conn = NULL; | 166 | cmd->conn = NULL; |
| 167 | spin_unlock(&cr->conn_recovery_cmd_lock); | 167 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| 168 | iscsit_free_cmd(cmd); | 168 | iscsit_free_cmd(cmd, true); |
| 169 | spin_lock(&cr->conn_recovery_cmd_lock); | 169 | spin_lock(&cr->conn_recovery_cmd_lock); |
| 170 | } | 170 | } |
| 171 | spin_unlock(&cr->conn_recovery_cmd_lock); | 171 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| @@ -248,7 +248,7 @@ void iscsit_discard_cr_cmds_by_expstatsn( | |||
| 248 | iscsit_remove_cmd_from_connection_recovery(cmd, sess); | 248 | iscsit_remove_cmd_from_connection_recovery(cmd, sess); |
| 249 | 249 | ||
| 250 | spin_unlock(&cr->conn_recovery_cmd_lock); | 250 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| 251 | iscsit_free_cmd(cmd); | 251 | iscsit_free_cmd(cmd, true); |
| 252 | spin_lock(&cr->conn_recovery_cmd_lock); | 252 | spin_lock(&cr->conn_recovery_cmd_lock); |
| 253 | } | 253 | } |
| 254 | spin_unlock(&cr->conn_recovery_cmd_lock); | 254 | spin_unlock(&cr->conn_recovery_cmd_lock); |
| @@ -302,7 +302,7 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn) | |||
| 302 | list_del(&cmd->i_conn_node); | 302 | list_del(&cmd->i_conn_node); |
| 303 | 303 | ||
| 304 | spin_unlock_bh(&conn->cmd_lock); | 304 | spin_unlock_bh(&conn->cmd_lock); |
| 305 | iscsit_free_cmd(cmd); | 305 | iscsit_free_cmd(cmd, true); |
| 306 | spin_lock_bh(&conn->cmd_lock); | 306 | spin_lock_bh(&conn->cmd_lock); |
| 307 | } | 307 | } |
| 308 | spin_unlock_bh(&conn->cmd_lock); | 308 | spin_unlock_bh(&conn->cmd_lock); |
| @@ -355,7 +355,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
| 355 | 355 | ||
| 356 | list_del(&cmd->i_conn_node); | 356 | list_del(&cmd->i_conn_node); |
| 357 | spin_unlock_bh(&conn->cmd_lock); | 357 | spin_unlock_bh(&conn->cmd_lock); |
| 358 | iscsit_free_cmd(cmd); | 358 | iscsit_free_cmd(cmd, true); |
| 359 | spin_lock_bh(&conn->cmd_lock); | 359 | spin_lock_bh(&conn->cmd_lock); |
| 360 | continue; | 360 | continue; |
| 361 | } | 361 | } |
| @@ -375,7 +375,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
| 375 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { | 375 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { |
| 376 | list_del(&cmd->i_conn_node); | 376 | list_del(&cmd->i_conn_node); |
| 377 | spin_unlock_bh(&conn->cmd_lock); | 377 | spin_unlock_bh(&conn->cmd_lock); |
| 378 | iscsit_free_cmd(cmd); | 378 | iscsit_free_cmd(cmd, true); |
| 379 | spin_lock_bh(&conn->cmd_lock); | 379 | spin_lock_bh(&conn->cmd_lock); |
| 380 | continue; | 380 | continue; |
| 381 | } | 381 | } |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index c2185fc31136..e38222191a33 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c | |||
| @@ -758,9 +758,9 @@ static int iscsi_add_notunderstood_response( | |||
| 758 | } | 758 | } |
| 759 | INIT_LIST_HEAD(&extra_response->er_list); | 759 | INIT_LIST_HEAD(&extra_response->er_list); |
| 760 | 760 | ||
| 761 | strncpy(extra_response->key, key, strlen(key) + 1); | 761 | strlcpy(extra_response->key, key, sizeof(extra_response->key)); |
| 762 | strncpy(extra_response->value, NOTUNDERSTOOD, | 762 | strlcpy(extra_response->value, NOTUNDERSTOOD, |
| 763 | strlen(NOTUNDERSTOOD) + 1); | 763 | sizeof(extra_response->value)); |
| 764 | 764 | ||
| 765 | list_add_tail(&extra_response->er_list, | 765 | list_add_tail(&extra_response->er_list, |
| 766 | ¶m_list->extra_response_list); | 766 | ¶m_list->extra_response_list); |
| @@ -1629,8 +1629,6 @@ int iscsi_decode_text_input( | |||
| 1629 | 1629 | ||
| 1630 | if (phase & PHASE_SECURITY) { | 1630 | if (phase & PHASE_SECURITY) { |
| 1631 | if (iscsi_check_for_auth_key(key) > 0) { | 1631 | if (iscsi_check_for_auth_key(key) > 0) { |
| 1632 | char *tmpptr = key + strlen(key); | ||
| 1633 | *tmpptr = '='; | ||
| 1634 | kfree(tmpbuf); | 1632 | kfree(tmpbuf); |
| 1635 | return 1; | 1633 | return 1; |
| 1636 | } | 1634 | } |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h index 915b06798505..a47046a752aa 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.h +++ b/drivers/target/iscsi/iscsi_target_parameters.h | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | #ifndef ISCSI_PARAMETERS_H | 1 | #ifndef ISCSI_PARAMETERS_H |
| 2 | #define ISCSI_PARAMETERS_H | 2 | #define ISCSI_PARAMETERS_H |
| 3 | 3 | ||
| 4 | #include <scsi/iscsi_proto.h> | ||
| 5 | |||
| 4 | struct iscsi_extra_response { | 6 | struct iscsi_extra_response { |
| 5 | char key[64]; | 7 | char key[KEY_MAXLEN]; |
| 6 | char value[32]; | 8 | char value[32]; |
| 7 | struct list_head er_list; | 9 | struct list_head er_list; |
| 8 | } ____cacheline_aligned; | 10 | } ____cacheline_aligned; |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 2cc6c9a3ffb8..08a3bacef0c5 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
| @@ -676,40 +676,56 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn) | |||
| 676 | 676 | ||
| 677 | void iscsit_release_cmd(struct iscsi_cmd *cmd) | 677 | void iscsit_release_cmd(struct iscsi_cmd *cmd) |
| 678 | { | 678 | { |
| 679 | struct iscsi_conn *conn = cmd->conn; | ||
| 680 | |||
| 681 | iscsit_free_r2ts_from_list(cmd); | ||
| 682 | iscsit_free_all_datain_reqs(cmd); | ||
| 683 | |||
| 684 | kfree(cmd->buf_ptr); | 679 | kfree(cmd->buf_ptr); |
| 685 | kfree(cmd->pdu_list); | 680 | kfree(cmd->pdu_list); |
| 686 | kfree(cmd->seq_list); | 681 | kfree(cmd->seq_list); |
| 687 | kfree(cmd->tmr_req); | 682 | kfree(cmd->tmr_req); |
| 688 | kfree(cmd->iov_data); | 683 | kfree(cmd->iov_data); |
| 689 | 684 | ||
| 690 | if (conn) { | 685 | kmem_cache_free(lio_cmd_cache, cmd); |
| 686 | } | ||
| 687 | |||
| 688 | static void __iscsit_free_cmd(struct iscsi_cmd *cmd, bool scsi_cmd, | ||
| 689 | bool check_queues) | ||
| 690 | { | ||
| 691 | struct iscsi_conn *conn = cmd->conn; | ||
| 692 | |||
| 693 | if (scsi_cmd) { | ||
| 694 | if (cmd->data_direction == DMA_TO_DEVICE) { | ||
| 695 | iscsit_stop_dataout_timer(cmd); | ||
| 696 | iscsit_free_r2ts_from_list(cmd); | ||
| 697 | } | ||
| 698 | if (cmd->data_direction == DMA_FROM_DEVICE) | ||
| 699 | iscsit_free_all_datain_reqs(cmd); | ||
| 700 | } | ||
| 701 | |||
| 702 | if (conn && check_queues) { | ||
| 691 | iscsit_remove_cmd_from_immediate_queue(cmd, conn); | 703 | iscsit_remove_cmd_from_immediate_queue(cmd, conn); |
| 692 | iscsit_remove_cmd_from_response_queue(cmd, conn); | 704 | iscsit_remove_cmd_from_response_queue(cmd, conn); |
| 693 | } | 705 | } |
| 694 | |||
| 695 | kmem_cache_free(lio_cmd_cache, cmd); | ||
| 696 | } | 706 | } |
| 697 | 707 | ||
| 698 | void iscsit_free_cmd(struct iscsi_cmd *cmd) | 708 | void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) |
| 699 | { | 709 | { |
| 710 | struct se_cmd *se_cmd = NULL; | ||
| 711 | int rc; | ||
| 700 | /* | 712 | /* |
| 701 | * Determine if a struct se_cmd is associated with | 713 | * Determine if a struct se_cmd is associated with |
| 702 | * this struct iscsi_cmd. | 714 | * this struct iscsi_cmd. |
| 703 | */ | 715 | */ |
| 704 | switch (cmd->iscsi_opcode) { | 716 | switch (cmd->iscsi_opcode) { |
| 705 | case ISCSI_OP_SCSI_CMD: | 717 | case ISCSI_OP_SCSI_CMD: |
| 706 | if (cmd->data_direction == DMA_TO_DEVICE) | 718 | se_cmd = &cmd->se_cmd; |
| 707 | iscsit_stop_dataout_timer(cmd); | 719 | __iscsit_free_cmd(cmd, true, shutdown); |
| 708 | /* | 720 | /* |
| 709 | * Fallthrough | 721 | * Fallthrough |
| 710 | */ | 722 | */ |
| 711 | case ISCSI_OP_SCSI_TMFUNC: | 723 | case ISCSI_OP_SCSI_TMFUNC: |
| 712 | transport_generic_free_cmd(&cmd->se_cmd, 1); | 724 | rc = transport_generic_free_cmd(&cmd->se_cmd, 1); |
| 725 | if (!rc && shutdown && se_cmd && se_cmd->se_sess) { | ||
| 726 | __iscsit_free_cmd(cmd, true, shutdown); | ||
| 727 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); | ||
| 728 | } | ||
| 713 | break; | 729 | break; |
| 714 | case ISCSI_OP_REJECT: | 730 | case ISCSI_OP_REJECT: |
| 715 | /* | 731 | /* |
| @@ -718,11 +734,19 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd) | |||
| 718 | * associated cmd->se_cmd needs to be released. | 734 | * associated cmd->se_cmd needs to be released. |
| 719 | */ | 735 | */ |
| 720 | if (cmd->se_cmd.se_tfo != NULL) { | 736 | if (cmd->se_cmd.se_tfo != NULL) { |
| 721 | transport_generic_free_cmd(&cmd->se_cmd, 1); | 737 | se_cmd = &cmd->se_cmd; |
| 738 | __iscsit_free_cmd(cmd, true, shutdown); | ||
| 739 | |||
| 740 | rc = transport_generic_free_cmd(&cmd->se_cmd, 1); | ||
| 741 | if (!rc && shutdown && se_cmd->se_sess) { | ||
| 742 | __iscsit_free_cmd(cmd, true, shutdown); | ||
| 743 | target_put_sess_cmd(se_cmd->se_sess, se_cmd); | ||
| 744 | } | ||
| 722 | break; | 745 | break; |
| 723 | } | 746 | } |
| 724 | /* Fall-through */ | 747 | /* Fall-through */ |
| 725 | default: | 748 | default: |
| 749 | __iscsit_free_cmd(cmd, false, shutdown); | ||
| 726 | cmd->release_cmd(cmd); | 750 | cmd->release_cmd(cmd); |
| 727 | break; | 751 | break; |
| 728 | } | 752 | } |
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 4f8e01a47081..a4422659d049 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h | |||
| @@ -29,7 +29,7 @@ extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_co | |||
| 29 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); | 29 | extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *); |
| 30 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); | 30 | extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); |
| 31 | extern void iscsit_release_cmd(struct iscsi_cmd *); | 31 | extern void iscsit_release_cmd(struct iscsi_cmd *); |
| 32 | extern void iscsit_free_cmd(struct iscsi_cmd *); | 32 | extern void iscsit_free_cmd(struct iscsi_cmd *, bool); |
| 33 | extern int iscsit_check_session_usage_count(struct iscsi_session *); | 33 | extern int iscsit_check_session_usage_count(struct iscsi_session *); |
| 34 | extern void iscsit_dec_session_usage_count(struct iscsi_session *); | 34 | extern void iscsit_dec_session_usage_count(struct iscsi_session *); |
| 35 | extern void iscsit_inc_session_usage_count(struct iscsi_session *); | 35 | extern void iscsit_inc_session_usage_count(struct iscsi_session *); |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 1b1d544e927a..b11890d85120 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
| @@ -153,6 +153,7 @@ static int fd_configure_device(struct se_device *dev) | |||
| 153 | struct request_queue *q = bdev_get_queue(inode->i_bdev); | 153 | struct request_queue *q = bdev_get_queue(inode->i_bdev); |
| 154 | unsigned long long dev_size; | 154 | unsigned long long dev_size; |
| 155 | 155 | ||
| 156 | fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev); | ||
| 156 | /* | 157 | /* |
| 157 | * Determine the number of bytes from i_size_read() minus | 158 | * Determine the number of bytes from i_size_read() minus |
| 158 | * one (1) logical sector from underlying struct block_device | 159 | * one (1) logical sector from underlying struct block_device |
| @@ -199,6 +200,7 @@ static int fd_configure_device(struct se_device *dev) | |||
| 199 | goto fail; | 200 | goto fail; |
| 200 | } | 201 | } |
| 201 | 202 | ||
| 203 | fd_dev->fd_block_size = FD_BLOCKSIZE; | ||
| 202 | /* | 204 | /* |
| 203 | * Limit UNMAP emulation to 8k Number of LBAs (NoLB) | 205 | * Limit UNMAP emulation to 8k Number of LBAs (NoLB) |
| 204 | */ | 206 | */ |
| @@ -217,9 +219,7 @@ static int fd_configure_device(struct se_device *dev) | |||
| 217 | dev->dev_attrib.max_write_same_len = 0x1000; | 219 | dev->dev_attrib.max_write_same_len = 0x1000; |
| 218 | } | 220 | } |
| 219 | 221 | ||
| 220 | fd_dev->fd_block_size = dev->dev_attrib.hw_block_size; | 222 | dev->dev_attrib.hw_block_size = fd_dev->fd_block_size; |
| 221 | |||
| 222 | dev->dev_attrib.hw_block_size = FD_BLOCKSIZE; | ||
| 223 | dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; | 223 | dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; |
| 224 | dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; | 224 | dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; |
| 225 | 225 | ||
| @@ -694,11 +694,12 @@ static sector_t fd_get_blocks(struct se_device *dev) | |||
| 694 | * to handle underlying block_device resize operations. | 694 | * to handle underlying block_device resize operations. |
| 695 | */ | 695 | */ |
| 696 | if (S_ISBLK(i->i_mode)) | 696 | if (S_ISBLK(i->i_mode)) |
| 697 | dev_size = (i_size_read(i) - fd_dev->fd_block_size); | 697 | dev_size = i_size_read(i); |
| 698 | else | 698 | else |
| 699 | dev_size = fd_dev->fd_dev_size; | 699 | dev_size = fd_dev->fd_dev_size; |
| 700 | 700 | ||
| 701 | return div_u64(dev_size, dev->dev_attrib.block_size); | 701 | return div_u64(dev_size - dev->dev_attrib.block_size, |
| 702 | dev->dev_attrib.block_size); | ||
| 702 | } | 703 | } |
| 703 | 704 | ||
| 704 | static struct sbc_ops fd_sbc_ops = { | 705 | static struct sbc_ops fd_sbc_ops = { |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4a793362309d..21e315874a54 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
| @@ -65,7 +65,7 @@ static void transport_complete_task_attr(struct se_cmd *cmd); | |||
| 65 | static void transport_handle_queue_full(struct se_cmd *cmd, | 65 | static void transport_handle_queue_full(struct se_cmd *cmd, |
| 66 | struct se_device *dev); | 66 | struct se_device *dev); |
| 67 | static int transport_generic_get_mem(struct se_cmd *cmd); | 67 | static int transport_generic_get_mem(struct se_cmd *cmd); |
| 68 | static void transport_put_cmd(struct se_cmd *cmd); | 68 | static int transport_put_cmd(struct se_cmd *cmd); |
| 69 | static void target_complete_ok_work(struct work_struct *work); | 69 | static void target_complete_ok_work(struct work_struct *work); |
| 70 | 70 | ||
| 71 | int init_se_kmem_caches(void) | 71 | int init_se_kmem_caches(void) |
| @@ -221,6 +221,7 @@ struct se_session *transport_init_session(void) | |||
| 221 | INIT_LIST_HEAD(&se_sess->sess_list); | 221 | INIT_LIST_HEAD(&se_sess->sess_list); |
| 222 | INIT_LIST_HEAD(&se_sess->sess_acl_list); | 222 | INIT_LIST_HEAD(&se_sess->sess_acl_list); |
| 223 | INIT_LIST_HEAD(&se_sess->sess_cmd_list); | 223 | INIT_LIST_HEAD(&se_sess->sess_cmd_list); |
| 224 | INIT_LIST_HEAD(&se_sess->sess_wait_list); | ||
| 224 | spin_lock_init(&se_sess->sess_cmd_lock); | 225 | spin_lock_init(&se_sess->sess_cmd_lock); |
| 225 | kref_init(&se_sess->sess_kref); | 226 | kref_init(&se_sess->sess_kref); |
| 226 | 227 | ||
| @@ -1943,7 +1944,7 @@ static inline void transport_free_pages(struct se_cmd *cmd) | |||
| 1943 | * This routine unconditionally frees a command, and reference counting | 1944 | * This routine unconditionally frees a command, and reference counting |
| 1944 | * or list removal must be done in the caller. | 1945 | * or list removal must be done in the caller. |
| 1945 | */ | 1946 | */ |
| 1946 | static void transport_release_cmd(struct se_cmd *cmd) | 1947 | static int transport_release_cmd(struct se_cmd *cmd) |
| 1947 | { | 1948 | { |
| 1948 | BUG_ON(!cmd->se_tfo); | 1949 | BUG_ON(!cmd->se_tfo); |
| 1949 | 1950 | ||
| @@ -1955,11 +1956,11 @@ static void transport_release_cmd(struct se_cmd *cmd) | |||
| 1955 | * If this cmd has been setup with target_get_sess_cmd(), drop | 1956 | * If this cmd has been setup with target_get_sess_cmd(), drop |
| 1956 | * the kref and call ->release_cmd() in kref callback. | 1957 | * the kref and call ->release_cmd() in kref callback. |
| 1957 | */ | 1958 | */ |
| 1958 | if (cmd->check_release != 0) { | 1959 | if (cmd->check_release != 0) |
| 1959 | target_put_sess_cmd(cmd->se_sess, cmd); | 1960 | return target_put_sess_cmd(cmd->se_sess, cmd); |
| 1960 | return; | 1961 | |
| 1961 | } | ||
| 1962 | cmd->se_tfo->release_cmd(cmd); | 1962 | cmd->se_tfo->release_cmd(cmd); |
| 1963 | return 1; | ||
| 1963 | } | 1964 | } |
| 1964 | 1965 | ||
| 1965 | /** | 1966 | /** |
| @@ -1968,7 +1969,7 @@ static void transport_release_cmd(struct se_cmd *cmd) | |||
| 1968 | * | 1969 | * |
| 1969 | * This routine releases our reference to the command and frees it if possible. | 1970 | * This routine releases our reference to the command and frees it if possible. |
| 1970 | */ | 1971 | */ |
| 1971 | static void transport_put_cmd(struct se_cmd *cmd) | 1972 | static int transport_put_cmd(struct se_cmd *cmd) |
| 1972 | { | 1973 | { |
| 1973 | unsigned long flags; | 1974 | unsigned long flags; |
| 1974 | 1975 | ||
| @@ -1976,7 +1977,7 @@ static void transport_put_cmd(struct se_cmd *cmd) | |||
| 1976 | if (atomic_read(&cmd->t_fe_count) && | 1977 | if (atomic_read(&cmd->t_fe_count) && |
| 1977 | !atomic_dec_and_test(&cmd->t_fe_count)) { | 1978 | !atomic_dec_and_test(&cmd->t_fe_count)) { |
| 1978 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 1979 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
| 1979 | return; | 1980 | return 0; |
| 1980 | } | 1981 | } |
| 1981 | 1982 | ||
| 1982 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { | 1983 | if (cmd->transport_state & CMD_T_DEV_ACTIVE) { |
| @@ -1986,8 +1987,7 @@ static void transport_put_cmd(struct se_cmd *cmd) | |||
| 1986 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 1987 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
| 1987 | 1988 | ||
| 1988 | transport_free_pages(cmd); | 1989 | transport_free_pages(cmd); |
| 1989 | transport_release_cmd(cmd); | 1990 | return transport_release_cmd(cmd); |
| 1990 | return; | ||
| 1991 | } | 1991 | } |
| 1992 | 1992 | ||
| 1993 | void *transport_kmap_data_sg(struct se_cmd *cmd) | 1993 | void *transport_kmap_data_sg(struct se_cmd *cmd) |
| @@ -2152,13 +2152,15 @@ static void transport_write_pending_qf(struct se_cmd *cmd) | |||
| 2152 | } | 2152 | } |
| 2153 | } | 2153 | } |
| 2154 | 2154 | ||
| 2155 | void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) | 2155 | int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) |
| 2156 | { | 2156 | { |
| 2157 | int ret = 0; | ||
| 2158 | |||
| 2157 | if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { | 2159 | if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) { |
| 2158 | if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) | 2160 | if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) |
| 2159 | transport_wait_for_tasks(cmd); | 2161 | transport_wait_for_tasks(cmd); |
| 2160 | 2162 | ||
| 2161 | transport_release_cmd(cmd); | 2163 | ret = transport_release_cmd(cmd); |
| 2162 | } else { | 2164 | } else { |
| 2163 | if (wait_for_tasks) | 2165 | if (wait_for_tasks) |
| 2164 | transport_wait_for_tasks(cmd); | 2166 | transport_wait_for_tasks(cmd); |
| @@ -2166,8 +2168,9 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) | |||
| 2166 | if (cmd->se_lun) | 2168 | if (cmd->se_lun) |
| 2167 | transport_lun_remove_cmd(cmd); | 2169 | transport_lun_remove_cmd(cmd); |
| 2168 | 2170 | ||
| 2169 | transport_put_cmd(cmd); | 2171 | ret = transport_put_cmd(cmd); |
| 2170 | } | 2172 | } |
| 2173 | return ret; | ||
| 2171 | } | 2174 | } |
| 2172 | EXPORT_SYMBOL(transport_generic_free_cmd); | 2175 | EXPORT_SYMBOL(transport_generic_free_cmd); |
| 2173 | 2176 | ||
| @@ -2250,11 +2253,14 @@ void target_sess_cmd_list_set_waiting(struct se_session *se_sess) | |||
| 2250 | unsigned long flags; | 2253 | unsigned long flags; |
| 2251 | 2254 | ||
| 2252 | spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); | 2255 | spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); |
| 2253 | 2256 | if (se_sess->sess_tearing_down) { | |
| 2254 | WARN_ON(se_sess->sess_tearing_down); | 2257 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
| 2258 | return; | ||
| 2259 | } | ||
| 2255 | se_sess->sess_tearing_down = 1; | 2260 | se_sess->sess_tearing_down = 1; |
| 2261 | list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list); | ||
| 2256 | 2262 | ||
| 2257 | list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) | 2263 | list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list) |
| 2258 | se_cmd->cmd_wait_set = 1; | 2264 | se_cmd->cmd_wait_set = 1; |
| 2259 | 2265 | ||
| 2260 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | 2266 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
| @@ -2263,44 +2269,32 @@ EXPORT_SYMBOL(target_sess_cmd_list_set_waiting); | |||
| 2263 | 2269 | ||
| 2264 | /* target_wait_for_sess_cmds - Wait for outstanding descriptors | 2270 | /* target_wait_for_sess_cmds - Wait for outstanding descriptors |
| 2265 | * @se_sess: session to wait for active I/O | 2271 | * @se_sess: session to wait for active I/O |
| 2266 | * @wait_for_tasks: Make extra transport_wait_for_tasks call | ||
| 2267 | */ | 2272 | */ |
| 2268 | void target_wait_for_sess_cmds( | 2273 | void target_wait_for_sess_cmds(struct se_session *se_sess) |
| 2269 | struct se_session *se_sess, | ||
| 2270 | int wait_for_tasks) | ||
| 2271 | { | 2274 | { |
| 2272 | struct se_cmd *se_cmd, *tmp_cmd; | 2275 | struct se_cmd *se_cmd, *tmp_cmd; |
| 2273 | bool rc = false; | 2276 | unsigned long flags; |
| 2274 | 2277 | ||
| 2275 | list_for_each_entry_safe(se_cmd, tmp_cmd, | 2278 | list_for_each_entry_safe(se_cmd, tmp_cmd, |
| 2276 | &se_sess->sess_cmd_list, se_cmd_list) { | 2279 | &se_sess->sess_wait_list, se_cmd_list) { |
| 2277 | list_del(&se_cmd->se_cmd_list); | 2280 | list_del(&se_cmd->se_cmd_list); |
| 2278 | 2281 | ||
| 2279 | pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:" | 2282 | pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:" |
| 2280 | " %d\n", se_cmd, se_cmd->t_state, | 2283 | " %d\n", se_cmd, se_cmd->t_state, |
| 2281 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | 2284 | se_cmd->se_tfo->get_cmd_state(se_cmd)); |
| 2282 | 2285 | ||
| 2283 | if (wait_for_tasks) { | 2286 | wait_for_completion(&se_cmd->cmd_wait_comp); |
| 2284 | pr_debug("Calling transport_wait_for_tasks se_cmd: %p t_state: %d," | 2287 | pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d" |
| 2285 | " fabric state: %d\n", se_cmd, se_cmd->t_state, | 2288 | " fabric state: %d\n", se_cmd, se_cmd->t_state, |
| 2286 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | 2289 | se_cmd->se_tfo->get_cmd_state(se_cmd)); |
| 2287 | |||
| 2288 | rc = transport_wait_for_tasks(se_cmd); | ||
| 2289 | |||
| 2290 | pr_debug("After transport_wait_for_tasks se_cmd: %p t_state: %d," | ||
| 2291 | " fabric state: %d\n", se_cmd, se_cmd->t_state, | ||
| 2292 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | ||
| 2293 | } | ||
| 2294 | |||
| 2295 | if (!rc) { | ||
| 2296 | wait_for_completion(&se_cmd->cmd_wait_comp); | ||
| 2297 | pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d" | ||
| 2298 | " fabric state: %d\n", se_cmd, se_cmd->t_state, | ||
| 2299 | se_cmd->se_tfo->get_cmd_state(se_cmd)); | ||
| 2300 | } | ||
| 2301 | 2290 | ||
| 2302 | se_cmd->se_tfo->release_cmd(se_cmd); | 2291 | se_cmd->se_tfo->release_cmd(se_cmd); |
| 2303 | } | 2292 | } |
| 2293 | |||
| 2294 | spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); | ||
| 2295 | WARN_ON(!list_empty(&se_sess->sess_cmd_list)); | ||
| 2296 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | ||
| 2297 | |||
| 2304 | } | 2298 | } |
| 2305 | EXPORT_SYMBOL(target_wait_for_sess_cmds); | 2299 | EXPORT_SYMBOL(target_wait_for_sess_cmds); |
| 2306 | 2300 | ||
