mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-27 04:54:41 +08:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger: "Here are the target-pending fixes for v4.12-rc7 that have been queued up for the last 2 weeks. This includes: - Fix a TMR related kref underflow detected by the recent refcount_t conversion in upstream. - Fix a iscsi-target corner case during explicit connection logout timeout failure. - Address last fallout in iscsi-target immediate data handling from v4.4 target-core now allowing control CDB payload underflow" * git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: iscsi-target: Reject immediate data underflow larger than SCSI transfer length iscsi-target: Fix delayed logout processing greater than SECONDS_FOR_LOGOUT_COMP target: Fix kref->refcount underflow in transport_cmd_finish_abort
This commit is contained in:
commit
d5d5c1825e
@ -1279,6 +1279,18 @@ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
|
||||
*/
|
||||
if (dump_payload)
|
||||
goto after_immediate_data;
|
||||
/*
|
||||
* Check for underflow case where both EDTL and immediate data payload
|
||||
* exceeds what is presented by CDB's TRANSFER LENGTH, and what has
|
||||
* already been set in target_cmd_size_check() as se_cmd->data_length.
|
||||
*
|
||||
* For this special case, fail the command and dump the immediate data
|
||||
* payload.
|
||||
*/
|
||||
if (cmd->first_burst_len > cmd->se_cmd.data_length) {
|
||||
cmd->sense_reason = TCM_INVALID_CDB_FIELD;
|
||||
goto after_immediate_data;
|
||||
}
|
||||
|
||||
immed_ret = iscsit_handle_immediate_data(cmd, hdr,
|
||||
cmd->first_burst_len);
|
||||
@ -4423,8 +4435,11 @@ static void iscsit_logout_post_handler_closesession(
|
||||
* always sleep waiting for RX/TX thread shutdown to complete
|
||||
* within iscsit_close_connection().
|
||||
*/
|
||||
if (!conn->conn_transport->rdma_shutdown)
|
||||
if (!conn->conn_transport->rdma_shutdown) {
|
||||
sleep = cmpxchg(&conn->tx_thread_active, true, false);
|
||||
if (!sleep)
|
||||
return;
|
||||
}
|
||||
|
||||
atomic_set(&conn->conn_logout_remove, 0);
|
||||
complete(&conn->conn_logout_comp);
|
||||
@ -4440,8 +4455,11 @@ static void iscsit_logout_post_handler_samecid(
|
||||
{
|
||||
int sleep = 1;
|
||||
|
||||
if (!conn->conn_transport->rdma_shutdown)
|
||||
if (!conn->conn_transport->rdma_shutdown) {
|
||||
sleep = cmpxchg(&conn->tx_thread_active, true, false);
|
||||
if (!sleep)
|
||||
return;
|
||||
}
|
||||
|
||||
atomic_set(&conn->conn_logout_remove, 0);
|
||||
complete(&conn->conn_logout_comp);
|
||||
|
@ -136,7 +136,7 @@ int init_se_kmem_caches(void);
|
||||
void release_se_kmem_caches(void);
|
||||
u32 scsi_get_new_index(scsi_index_t);
|
||||
void transport_subsystem_check_init(void);
|
||||
void transport_cmd_finish_abort(struct se_cmd *, int);
|
||||
int transport_cmd_finish_abort(struct se_cmd *, int);
|
||||
unsigned char *transport_dump_cmd_direction(struct se_cmd *);
|
||||
void transport_dump_dev_state(struct se_device *, char *, int *);
|
||||
void transport_dump_dev_info(struct se_device *, struct se_lun *,
|
||||
|
@ -75,7 +75,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
|
||||
kfree(tmr);
|
||||
}
|
||||
|
||||
static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
|
||||
static int core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
|
||||
{
|
||||
unsigned long flags;
|
||||
bool remove = true, send_tas;
|
||||
@ -91,7 +91,7 @@ static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
|
||||
transport_send_task_abort(cmd);
|
||||
}
|
||||
|
||||
transport_cmd_finish_abort(cmd, remove);
|
||||
return transport_cmd_finish_abort(cmd, remove);
|
||||
}
|
||||
|
||||
static int target_check_cdb_and_preempt(struct list_head *list,
|
||||
@ -184,8 +184,8 @@ void core_tmr_abort_task(
|
||||
cancel_work_sync(&se_cmd->work);
|
||||
transport_wait_for_tasks(se_cmd);
|
||||
|
||||
transport_cmd_finish_abort(se_cmd, true);
|
||||
target_put_sess_cmd(se_cmd);
|
||||
if (!transport_cmd_finish_abort(se_cmd, true))
|
||||
target_put_sess_cmd(se_cmd);
|
||||
|
||||
printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
|
||||
" ref_tag: %llu\n", ref_tag);
|
||||
@ -281,8 +281,8 @@ static void core_tmr_drain_tmr_list(
|
||||
cancel_work_sync(&cmd->work);
|
||||
transport_wait_for_tasks(cmd);
|
||||
|
||||
transport_cmd_finish_abort(cmd, 1);
|
||||
target_put_sess_cmd(cmd);
|
||||
if (!transport_cmd_finish_abort(cmd, 1))
|
||||
target_put_sess_cmd(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,8 +380,8 @@ static void core_tmr_drain_state_list(
|
||||
cancel_work_sync(&cmd->work);
|
||||
transport_wait_for_tasks(cmd);
|
||||
|
||||
core_tmr_handle_tas_abort(cmd, tas);
|
||||
target_put_sess_cmd(cmd);
|
||||
if (!core_tmr_handle_tas_abort(cmd, tas))
|
||||
target_put_sess_cmd(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,9 +651,10 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd)
|
||||
percpu_ref_put(&lun->lun_ref);
|
||||
}
|
||||
|
||||
void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
|
||||
int transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
|
||||
{
|
||||
bool ack_kref = (cmd->se_cmd_flags & SCF_ACK_KREF);
|
||||
int ret = 0;
|
||||
|
||||
if (cmd->se_cmd_flags & SCF_SE_LUN_CMD)
|
||||
transport_lun_remove_cmd(cmd);
|
||||
@ -665,9 +666,11 @@ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
|
||||
cmd->se_tfo->aborted_task(cmd);
|
||||
|
||||
if (transport_cmd_check_stop_to_fabric(cmd))
|
||||
return;
|
||||
return 1;
|
||||
if (remove && ack_kref)
|
||||
transport_put_cmd(cmd);
|
||||
ret = transport_put_cmd(cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void target_complete_failure_work(struct work_struct *work)
|
||||
|
Loading…
Reference in New Issue
Block a user