diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-29 12:03:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-29 12:03:57 -0500 |
commit | 36511e86079c57077493a07be60b39376d7cea74 (patch) | |
tree | 32803a94b1c33ad352943fd8e62d77b71c31259f | |
parent | 75a29ec1e833de4aeac21ef60e20f9ecf822d481 (diff) | |
parent | 8f90353950b2da8d877c6ac3dde5e1109257a117 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger:
- fix tcm-user backend driver expired cmd time processing (agrover)
- eliminate kref_put_spinlock_irqsave() for I/O completion (bart)
- fix iscsi login kthread failure case hung task regression (nab)
- fix COMPARE_AND_WRITE completion use-after-free race (nab)
- fix COMPARE_AND_WRITE with SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC non zero
SGL offset data corruption. (Jan + Doug)
- fix >= v4.4-rc1 regression for tcm_qla2xxx enable configfs attribute
(Himanshu + HCH)
* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
target/stat: print full t10_wwn.model buffer
target: fix COMPARE_AND_WRITE non zero SGL offset data corruption
qla2xxx: Fix regression introduced by target configFS changes
kref: Remove kref_put_spinlock_irqsave()
target: Invoke release_cmd() callback without holding a spinlock
target: Fix race for SCF_COMPARE_AND_WRITE_POST checking
iscsi-target: Fix rx_login_comp hang after login failure
iscsi-target: return -ENOMEM instead of -1 in case of failed kmalloc()
target/user: Do not set unused fields in tcmu_ops
target/user: Fix time calc in expired cmd processing
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 13 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_nego.c | 1 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_parameters.c | 10 | ||||
-rw-r--r-- | drivers/target/target_core_sbc.c | 17 | ||||
-rw-r--r-- | drivers/target/target_core_stat.c | 2 | ||||
-rw-r--r-- | drivers/target/target_core_tmr.c | 7 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 26 | ||||
-rw-r--r-- | drivers/target/target_core_user.c | 4 | ||||
-rw-r--r-- | include/linux/kref.h | 33 | ||||
-rw-r--r-- | include/target/target_core_base.h | 2 |
11 files changed, 53 insertions, 64 deletions
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 3ba2e9564b9a..81af294f15a7 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -902,7 +902,7 @@ static ssize_t tcm_qla2xxx_tpg_fabric_prot_type_show(struct config_item *item, | |||
902 | return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type); | 902 | return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type); |
903 | } | 903 | } |
904 | 904 | ||
905 | CONFIGFS_ATTR_WO(tcm_qla2xxx_tpg_, enable); | 905 | CONFIGFS_ATTR(tcm_qla2xxx_tpg_, enable); |
906 | CONFIGFS_ATTR_RO(tcm_qla2xxx_tpg_, dynamic_sessions); | 906 | CONFIGFS_ATTR_RO(tcm_qla2xxx_tpg_, dynamic_sessions); |
907 | CONFIGFS_ATTR(tcm_qla2xxx_tpg_, fabric_prot_type); | 907 | CONFIGFS_ATTR(tcm_qla2xxx_tpg_, fabric_prot_type); |
908 | 908 | ||
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 342a07c58d89..72204fbf2bb1 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -4074,6 +4074,17 @@ reject: | |||
4074 | return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); | 4074 | return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); |
4075 | } | 4075 | } |
4076 | 4076 | ||
4077 | static bool iscsi_target_check_conn_state(struct iscsi_conn *conn) | ||
4078 | { | ||
4079 | bool ret; | ||
4080 | |||
4081 | spin_lock_bh(&conn->state_lock); | ||
4082 | ret = (conn->conn_state != TARG_CONN_STATE_LOGGED_IN); | ||
4083 | spin_unlock_bh(&conn->state_lock); | ||
4084 | |||
4085 | return ret; | ||
4086 | } | ||
4087 | |||
4077 | int iscsi_target_rx_thread(void *arg) | 4088 | int iscsi_target_rx_thread(void *arg) |
4078 | { | 4089 | { |
4079 | int ret, rc; | 4090 | int ret, rc; |
@@ -4091,7 +4102,7 @@ int iscsi_target_rx_thread(void *arg) | |||
4091 | * incoming iscsi/tcp socket I/O, and/or failing the connection. | 4102 | * incoming iscsi/tcp socket I/O, and/or failing the connection. |
4092 | */ | 4103 | */ |
4093 | rc = wait_for_completion_interruptible(&conn->rx_login_comp); | 4104 | rc = wait_for_completion_interruptible(&conn->rx_login_comp); |
4094 | if (rc < 0) | 4105 | if (rc < 0 || iscsi_target_check_conn_state(conn)) |
4095 | return 0; | 4106 | return 0; |
4096 | 4107 | ||
4097 | if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { | 4108 | if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 5c964c09c89f..9fc9117d0f22 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -388,6 +388,7 @@ err: | |||
388 | if (login->login_complete) { | 388 | if (login->login_complete) { |
389 | if (conn->rx_thread && conn->rx_thread_active) { | 389 | if (conn->rx_thread && conn->rx_thread_active) { |
390 | send_sig(SIGINT, conn->rx_thread, 1); | 390 | send_sig(SIGINT, conn->rx_thread, 1); |
391 | complete(&conn->rx_login_comp); | ||
391 | kthread_stop(conn->rx_thread); | 392 | kthread_stop(conn->rx_thread); |
392 | } | 393 | } |
393 | if (conn->tx_thread && conn->tx_thread_active) { | 394 | if (conn->tx_thread && conn->tx_thread_active) { |
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 51d1734d5390..2cbea2af7cd0 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c | |||
@@ -208,7 +208,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) | |||
208 | if (!pl) { | 208 | if (!pl) { |
209 | pr_err("Unable to allocate memory for" | 209 | pr_err("Unable to allocate memory for" |
210 | " struct iscsi_param_list.\n"); | 210 | " struct iscsi_param_list.\n"); |
211 | return -1 ; | 211 | return -ENOMEM; |
212 | } | 212 | } |
213 | INIT_LIST_HEAD(&pl->param_list); | 213 | INIT_LIST_HEAD(&pl->param_list); |
214 | INIT_LIST_HEAD(&pl->extra_response_list); | 214 | INIT_LIST_HEAD(&pl->extra_response_list); |
@@ -578,7 +578,7 @@ int iscsi_copy_param_list( | |||
578 | param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL); | 578 | param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL); |
579 | if (!param_list) { | 579 | if (!param_list) { |
580 | pr_err("Unable to allocate memory for struct iscsi_param_list.\n"); | 580 | pr_err("Unable to allocate memory for struct iscsi_param_list.\n"); |
581 | return -1; | 581 | return -ENOMEM; |
582 | } | 582 | } |
583 | INIT_LIST_HEAD(¶m_list->param_list); | 583 | INIT_LIST_HEAD(¶m_list->param_list); |
584 | INIT_LIST_HEAD(¶m_list->extra_response_list); | 584 | INIT_LIST_HEAD(¶m_list->extra_response_list); |
@@ -629,7 +629,7 @@ int iscsi_copy_param_list( | |||
629 | 629 | ||
630 | err_out: | 630 | err_out: |
631 | iscsi_release_param_list(param_list); | 631 | iscsi_release_param_list(param_list); |
632 | return -1; | 632 | return -ENOMEM; |
633 | } | 633 | } |
634 | 634 | ||
635 | static void iscsi_release_extra_responses(struct iscsi_param_list *param_list) | 635 | static void iscsi_release_extra_responses(struct iscsi_param_list *param_list) |
@@ -729,7 +729,7 @@ static int iscsi_add_notunderstood_response( | |||
729 | if (!extra_response) { | 729 | if (!extra_response) { |
730 | pr_err("Unable to allocate memory for" | 730 | pr_err("Unable to allocate memory for" |
731 | " struct iscsi_extra_response.\n"); | 731 | " struct iscsi_extra_response.\n"); |
732 | return -1; | 732 | return -ENOMEM; |
733 | } | 733 | } |
734 | INIT_LIST_HEAD(&extra_response->er_list); | 734 | INIT_LIST_HEAD(&extra_response->er_list); |
735 | 735 | ||
@@ -1370,7 +1370,7 @@ int iscsi_decode_text_input( | |||
1370 | tmpbuf = kzalloc(length + 1, GFP_KERNEL); | 1370 | tmpbuf = kzalloc(length + 1, GFP_KERNEL); |
1371 | if (!tmpbuf) { | 1371 | if (!tmpbuf) { |
1372 | pr_err("Unable to allocate %u + 1 bytes for tmpbuf.\n", length); | 1372 | pr_err("Unable to allocate %u + 1 bytes for tmpbuf.\n", length); |
1373 | return -1; | 1373 | return -ENOMEM; |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | memcpy(tmpbuf, textbuf, length); | 1376 | memcpy(tmpbuf, textbuf, length); |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 0b4b2a67d9f9..98698d875742 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -371,7 +371,8 @@ sbc_setup_write_same(struct se_cmd *cmd, unsigned char *flags, struct sbc_ops *o | |||
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | 373 | ||
374 | static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success) | 374 | static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success, |
375 | int *post_ret) | ||
375 | { | 376 | { |
376 | unsigned char *buf, *addr; | 377 | unsigned char *buf, *addr; |
377 | struct scatterlist *sg; | 378 | struct scatterlist *sg; |
@@ -437,7 +438,8 @@ sbc_execute_rw(struct se_cmd *cmd) | |||
437 | cmd->data_direction); | 438 | cmd->data_direction); |
438 | } | 439 | } |
439 | 440 | ||
440 | static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success) | 441 | static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success, |
442 | int *post_ret) | ||
441 | { | 443 | { |
442 | struct se_device *dev = cmd->se_dev; | 444 | struct se_device *dev = cmd->se_dev; |
443 | 445 | ||
@@ -447,8 +449,10 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success) | |||
447 | * sent to the backend driver. | 449 | * sent to the backend driver. |
448 | */ | 450 | */ |
449 | spin_lock_irq(&cmd->t_state_lock); | 451 | spin_lock_irq(&cmd->t_state_lock); |
450 | if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) | 452 | if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) { |
451 | cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST; | 453 | cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST; |
454 | *post_ret = 1; | ||
455 | } | ||
452 | spin_unlock_irq(&cmd->t_state_lock); | 456 | spin_unlock_irq(&cmd->t_state_lock); |
453 | 457 | ||
454 | /* | 458 | /* |
@@ -460,7 +464,8 @@ static sense_reason_t compare_and_write_post(struct se_cmd *cmd, bool success) | |||
460 | return TCM_NO_SENSE; | 464 | return TCM_NO_SENSE; |
461 | } | 465 | } |
462 | 466 | ||
463 | static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success) | 467 | static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success, |
468 | int *post_ret) | ||
464 | { | 469 | { |
465 | struct se_device *dev = cmd->se_dev; | 470 | struct se_device *dev = cmd->se_dev; |
466 | struct scatterlist *write_sg = NULL, *sg; | 471 | struct scatterlist *write_sg = NULL, *sg; |
@@ -556,11 +561,11 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes | |||
556 | 561 | ||
557 | if (block_size < PAGE_SIZE) { | 562 | if (block_size < PAGE_SIZE) { |
558 | sg_set_page(&write_sg[i], m.page, block_size, | 563 | sg_set_page(&write_sg[i], m.page, block_size, |
559 | block_size); | 564 | m.piter.sg->offset + block_size); |
560 | } else { | 565 | } else { |
561 | sg_miter_next(&m); | 566 | sg_miter_next(&m); |
562 | sg_set_page(&write_sg[i], m.page, block_size, | 567 | sg_set_page(&write_sg[i], m.page, block_size, |
563 | 0); | 568 | m.piter.sg->offset); |
564 | } | 569 | } |
565 | len -= block_size; | 570 | len -= block_size; |
566 | i++; | 571 | i++; |
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c index 273c72b2b83d..81a6b3e07687 100644 --- a/drivers/target/target_core_stat.c +++ b/drivers/target/target_core_stat.c | |||
@@ -246,7 +246,7 @@ static ssize_t target_stat_lu_prod_show(struct config_item *item, char *page) | |||
246 | char str[sizeof(dev->t10_wwn.model)+1]; | 246 | char str[sizeof(dev->t10_wwn.model)+1]; |
247 | 247 | ||
248 | /* scsiLuProductId */ | 248 | /* scsiLuProductId */ |
249 | for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++) | 249 | for (i = 0; i < sizeof(dev->t10_wwn.model); i++) |
250 | str[i] = ISPRINT(dev->t10_wwn.model[i]) ? | 250 | str[i] = ISPRINT(dev->t10_wwn.model[i]) ? |
251 | dev->t10_wwn.model[i] : ' '; | 251 | dev->t10_wwn.model[i] : ' '; |
252 | str[i] = '\0'; | 252 | str[i] = '\0'; |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 5b2820312310..28fb3016370f 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -130,6 +130,9 @@ void core_tmr_abort_task( | |||
130 | if (tmr->ref_task_tag != ref_tag) | 130 | if (tmr->ref_task_tag != ref_tag) |
131 | continue; | 131 | continue; |
132 | 132 | ||
133 | if (!kref_get_unless_zero(&se_cmd->cmd_kref)) | ||
134 | continue; | ||
135 | |||
133 | printk("ABORT_TASK: Found referenced %s task_tag: %llu\n", | 136 | printk("ABORT_TASK: Found referenced %s task_tag: %llu\n", |
134 | se_cmd->se_tfo->get_fabric_name(), ref_tag); | 137 | se_cmd->se_tfo->get_fabric_name(), ref_tag); |
135 | 138 | ||
@@ -139,13 +142,15 @@ void core_tmr_abort_task( | |||
139 | " skipping\n", ref_tag); | 142 | " skipping\n", ref_tag); |
140 | spin_unlock(&se_cmd->t_state_lock); | 143 | spin_unlock(&se_cmd->t_state_lock); |
141 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | 144 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
145 | |||
146 | target_put_sess_cmd(se_cmd); | ||
147 | |||
142 | goto out; | 148 | goto out; |
143 | } | 149 | } |
144 | se_cmd->transport_state |= CMD_T_ABORTED; | 150 | se_cmd->transport_state |= CMD_T_ABORTED; |
145 | spin_unlock(&se_cmd->t_state_lock); | 151 | spin_unlock(&se_cmd->t_state_lock); |
146 | 152 | ||
147 | list_del_init(&se_cmd->se_cmd_list); | 153 | list_del_init(&se_cmd->se_cmd_list); |
148 | kref_get(&se_cmd->cmd_kref); | ||
149 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); | 154 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
150 | 155 | ||
151 | cancel_work_sync(&se_cmd->work); | 156 | cancel_work_sync(&se_cmd->work); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 5bacc7b5ed6d..4fdcee2006d1 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1658,7 +1658,7 @@ bool target_stop_cmd(struct se_cmd *cmd, unsigned long *flags) | |||
1658 | void transport_generic_request_failure(struct se_cmd *cmd, | 1658 | void transport_generic_request_failure(struct se_cmd *cmd, |
1659 | sense_reason_t sense_reason) | 1659 | sense_reason_t sense_reason) |
1660 | { | 1660 | { |
1661 | int ret = 0; | 1661 | int ret = 0, post_ret = 0; |
1662 | 1662 | ||
1663 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08llx" | 1663 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08llx" |
1664 | " CDB: 0x%02x\n", cmd, cmd->tag, cmd->t_task_cdb[0]); | 1664 | " CDB: 0x%02x\n", cmd, cmd->tag, cmd->t_task_cdb[0]); |
@@ -1680,7 +1680,7 @@ void transport_generic_request_failure(struct se_cmd *cmd, | |||
1680 | */ | 1680 | */ |
1681 | if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) && | 1681 | if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) && |
1682 | cmd->transport_complete_callback) | 1682 | cmd->transport_complete_callback) |
1683 | cmd->transport_complete_callback(cmd, false); | 1683 | cmd->transport_complete_callback(cmd, false, &post_ret); |
1684 | 1684 | ||
1685 | switch (sense_reason) { | 1685 | switch (sense_reason) { |
1686 | case TCM_NON_EXISTENT_LUN: | 1686 | case TCM_NON_EXISTENT_LUN: |
@@ -2068,11 +2068,13 @@ static void target_complete_ok_work(struct work_struct *work) | |||
2068 | */ | 2068 | */ |
2069 | if (cmd->transport_complete_callback) { | 2069 | if (cmd->transport_complete_callback) { |
2070 | sense_reason_t rc; | 2070 | sense_reason_t rc; |
2071 | bool caw = (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE); | ||
2072 | bool zero_dl = !(cmd->data_length); | ||
2073 | int post_ret = 0; | ||
2071 | 2074 | ||
2072 | rc = cmd->transport_complete_callback(cmd, true); | 2075 | rc = cmd->transport_complete_callback(cmd, true, &post_ret); |
2073 | if (!rc && !(cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE_POST)) { | 2076 | if (!rc && !post_ret) { |
2074 | if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) && | 2077 | if (caw && zero_dl) |
2075 | !cmd->data_length) | ||
2076 | goto queue_rsp; | 2078 | goto queue_rsp; |
2077 | 2079 | ||
2078 | return; | 2080 | return; |
@@ -2507,23 +2509,24 @@ out: | |||
2507 | EXPORT_SYMBOL(target_get_sess_cmd); | 2509 | EXPORT_SYMBOL(target_get_sess_cmd); |
2508 | 2510 | ||
2509 | static void target_release_cmd_kref(struct kref *kref) | 2511 | static void target_release_cmd_kref(struct kref *kref) |
2510 | __releases(&se_cmd->se_sess->sess_cmd_lock) | ||
2511 | { | 2512 | { |
2512 | struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref); | 2513 | struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref); |
2513 | struct se_session *se_sess = se_cmd->se_sess; | 2514 | struct se_session *se_sess = se_cmd->se_sess; |
2515 | unsigned long flags; | ||
2514 | 2516 | ||
2517 | spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); | ||
2515 | if (list_empty(&se_cmd->se_cmd_list)) { | 2518 | if (list_empty(&se_cmd->se_cmd_list)) { |
2516 | spin_unlock(&se_sess->sess_cmd_lock); | 2519 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
2517 | se_cmd->se_tfo->release_cmd(se_cmd); | 2520 | se_cmd->se_tfo->release_cmd(se_cmd); |
2518 | return; | 2521 | return; |
2519 | } | 2522 | } |
2520 | if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) { | 2523 | if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) { |
2521 | spin_unlock(&se_sess->sess_cmd_lock); | 2524 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
2522 | complete(&se_cmd->cmd_wait_comp); | 2525 | complete(&se_cmd->cmd_wait_comp); |
2523 | return; | 2526 | return; |
2524 | } | 2527 | } |
2525 | list_del(&se_cmd->se_cmd_list); | 2528 | list_del(&se_cmd->se_cmd_list); |
2526 | spin_unlock(&se_sess->sess_cmd_lock); | 2529 | spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); |
2527 | 2530 | ||
2528 | se_cmd->se_tfo->release_cmd(se_cmd); | 2531 | se_cmd->se_tfo->release_cmd(se_cmd); |
2529 | } | 2532 | } |
@@ -2539,8 +2542,7 @@ int target_put_sess_cmd(struct se_cmd *se_cmd) | |||
2539 | se_cmd->se_tfo->release_cmd(se_cmd); | 2542 | se_cmd->se_tfo->release_cmd(se_cmd); |
2540 | return 1; | 2543 | return 1; |
2541 | } | 2544 | } |
2542 | return kref_put_spinlock_irqsave(&se_cmd->cmd_kref, target_release_cmd_kref, | 2545 | return kref_put(&se_cmd->cmd_kref, target_release_cmd_kref); |
2543 | &se_sess->sess_cmd_lock); | ||
2544 | } | 2546 | } |
2545 | EXPORT_SYMBOL(target_put_sess_cmd); | 2547 | EXPORT_SYMBOL(target_put_sess_cmd); |
2546 | 2548 | ||
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 937cebf76633..5e6d6cb348fc 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -638,7 +638,7 @@ static int tcmu_check_expired_cmd(int id, void *p, void *data) | |||
638 | if (test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) | 638 | if (test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) |
639 | return 0; | 639 | return 0; |
640 | 640 | ||
641 | if (!time_after(cmd->deadline, jiffies)) | 641 | if (!time_after(jiffies, cmd->deadline)) |
642 | return 0; | 642 | return 0; |
643 | 643 | ||
644 | set_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags); | 644 | set_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags); |
@@ -1101,8 +1101,6 @@ tcmu_parse_cdb(struct se_cmd *cmd) | |||
1101 | 1101 | ||
1102 | static const struct target_backend_ops tcmu_ops = { | 1102 | static const struct target_backend_ops tcmu_ops = { |
1103 | .name = "user", | 1103 | .name = "user", |
1104 | .inquiry_prod = "USER", | ||
1105 | .inquiry_rev = TCMU_VERSION, | ||
1106 | .owner = THIS_MODULE, | 1104 | .owner = THIS_MODULE, |
1107 | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, | 1105 | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, |
1108 | .attach_hba = tcmu_attach_hba, | 1106 | .attach_hba = tcmu_attach_hba, |
diff --git a/include/linux/kref.h b/include/linux/kref.h index 484604d184be..e15828fd71f1 100644 --- a/include/linux/kref.h +++ b/include/linux/kref.h | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/atomic.h> | 19 | #include <linux/atomic.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/spinlock.h> | ||
23 | 22 | ||
24 | struct kref { | 23 | struct kref { |
25 | atomic_t refcount; | 24 | atomic_t refcount; |
@@ -99,38 +98,6 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref) | |||
99 | return kref_sub(kref, 1, release); | 98 | return kref_sub(kref, 1, release); |
100 | } | 99 | } |
101 | 100 | ||
102 | /** | ||
103 | * kref_put_spinlock_irqsave - decrement refcount for object. | ||
104 | * @kref: object. | ||
105 | * @release: pointer to the function that will clean up the object when the | ||
106 | * last reference to the object is released. | ||
107 | * This pointer is required, and it is not acceptable to pass kfree | ||
108 | * in as this function. | ||
109 | * @lock: lock to take in release case | ||
110 | * | ||
111 | * Behaves identical to kref_put with one exception. If the reference count | ||
112 | * drops to zero, the lock will be taken atomically wrt dropping the reference | ||
113 | * count. The release function has to call spin_unlock() without _irqrestore. | ||
114 | */ | ||
115 | static inline int kref_put_spinlock_irqsave(struct kref *kref, | ||
116 | void (*release)(struct kref *kref), | ||
117 | spinlock_t *lock) | ||
118 | { | ||
119 | unsigned long flags; | ||
120 | |||
121 | WARN_ON(release == NULL); | ||
122 | if (atomic_add_unless(&kref->refcount, -1, 1)) | ||
123 | return 0; | ||
124 | spin_lock_irqsave(lock, flags); | ||
125 | if (atomic_dec_and_test(&kref->refcount)) { | ||
126 | release(kref); | ||
127 | local_irq_restore(flags); | ||
128 | return 1; | ||
129 | } | ||
130 | spin_unlock_irqrestore(lock, flags); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static inline int kref_put_mutex(struct kref *kref, | 101 | static inline int kref_put_mutex(struct kref *kref, |
135 | void (*release)(struct kref *kref), | 102 | void (*release)(struct kref *kref), |
136 | struct mutex *lock) | 103 | struct mutex *lock) |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 0a2c74008e53..aabf0aca0171 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -474,7 +474,7 @@ struct se_cmd { | |||
474 | struct completion cmd_wait_comp; | 474 | struct completion cmd_wait_comp; |
475 | const struct target_core_fabric_ops *se_tfo; | 475 | const struct target_core_fabric_ops *se_tfo; |
476 | sense_reason_t (*execute_cmd)(struct se_cmd *); | 476 | sense_reason_t (*execute_cmd)(struct se_cmd *); |
477 | sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool); | 477 | sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool, int *); |
478 | void *protocol_data; | 478 | void *protocol_data; |
479 | 479 | ||
480 | unsigned char *t_task_cdb; | 480 | unsigned char *t_task_cdb; |