diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 19:24:58 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 19:24:58 +0100 |
commit | bdb39c9509e6d31943cb29dbb6ccd1b64013fb98 (patch) | |
tree | 36bf88ee1db29c69f0e488b7f537b2907ebff095 /drivers/target | |
parent | Merge tag 'for-5.12/dm-changes' of git://git.kernel.org/pub/scm/linux/kernel/... (diff) | |
parent | scsi: MAINTAINERS: Adjust to reflect gdth scsi driver removal (diff) | |
download | linux-bdb39c9509e6d31943cb29dbb6ccd1b64013fb98.tar.xz linux-bdb39c9509e6d31943cb29dbb6ccd1b64013fb98.zip |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This series consists of the usual driver updates (ufs, ibmvfc,
qla2xxx, hisi_sas, pm80xx) plus the removal of the gdth driver (which
is bound to cause conflicts with a trivial change somewhere).
The only big major rework of note is the one from Hannes trying to
clean up our result handling code in the drivers to make it
consistent"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (194 commits)
scsi: MAINTAINERS: Adjust to reflect gdth scsi driver removal
scsi: ufs: Give clk scaling min gear a value
scsi: lpfc: Fix 'physical' typos
scsi: megaraid_mbox: Fix spelling of 'allocated'
scsi: qla2xxx: Simplify the calculation of variables
scsi: message: fusion: Fix 'physical' typos
scsi: target: core: Change ASCQ for residual write
scsi: target: core: Signal WRITE residuals
scsi: target: core: Set residuals for 4Kn devices
scsi: hisi_sas: Add trace FIFO debugfs support
scsi: hisi_sas: Flush workqueue in hisi_sas_v3_remove()
scsi: hisi_sas: Enable debugfs support by default
scsi: hisi_sas: Don't check .nr_hw_queues in hisi_sas_task_prep()
scsi: hisi_sas: Remove deferred probe check in hisi_sas_v2_probe()
scsi: lpfc: Add auto select on IRQ_POLL
scsi: ncr53c8xx: Fix typos
scsi: lpfc: Fix ancient double free
scsi: qla2xxx: Fix some memory corruption
scsi: qla2xxx: Remove redundant NULL check
scsi: megaraid: Fix ifnullfree.cocci warnings
...
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 20 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.h | 2 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_erl0.c | 2 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 11 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_util.h | 2 | ||||
-rw-r--r-- | drivers/target/target_core_alua.c | 2 | ||||
-rw-r--r-- | drivers/target/target_core_file.c | 2 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 65 |
8 files changed, 50 insertions, 56 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 518fac4864cf..d0e7ed8f28cc 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -4327,7 +4327,7 @@ int iscsit_close_connection( atomic_read(&sess->session_fall_back_to_erl0)) { spin_unlock_bh(&sess->conn_lock); complete_all(&sess->session_wait_comp); - iscsit_close_session(sess); + iscsit_close_session(sess, true); return 0; } else if (atomic_read(&sess->session_logout)) { @@ -4337,7 +4337,7 @@ int iscsit_close_connection( if (atomic_read(&sess->session_close)) { spin_unlock_bh(&sess->conn_lock); complete_all(&sess->session_wait_comp); - iscsit_close_session(sess); + iscsit_close_session(sess, true); } else { spin_unlock_bh(&sess->conn_lock); } @@ -4353,7 +4353,7 @@ int iscsit_close_connection( if (atomic_read(&sess->session_close)) { spin_unlock_bh(&sess->conn_lock); complete_all(&sess->session_wait_comp); - iscsit_close_session(sess); + iscsit_close_session(sess, true); } else { spin_unlock_bh(&sess->conn_lock); } @@ -4366,7 +4366,7 @@ int iscsit_close_connection( * If the iSCSI Session for the iSCSI Initiator Node exists, * forcefully shutdown the iSCSI NEXUS. */ -int iscsit_close_session(struct iscsi_session *sess) +int iscsit_close_session(struct iscsi_session *sess, bool can_sleep) { struct iscsi_portal_group *tpg = sess->tpg; struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; @@ -4399,14 +4399,10 @@ int iscsit_close_session(struct iscsi_session *sess) * time2retain handler) and contain and active session usage count we * restart the timer and exit. */ - if (!in_interrupt()) { - iscsit_check_session_usage_count(sess); - } else { - if (iscsit_check_session_usage_count(sess) == 2) { - atomic_set(&sess->session_logout, 0); - iscsit_start_time2retain_handler(sess); - return 0; - } + if (iscsit_check_session_usage_count(sess, can_sleep)) { + atomic_set(&sess->session_logout, 0); + iscsit_start_time2retain_handler(sess); + return 0; } transport_deregister_session(sess->se_sess); diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index 7409ce2a6607..b35a96ded9c1 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h @@ -41,7 +41,7 @@ extern void iscsit_thread_get_cpumask(struct iscsi_conn *); extern int iscsi_target_tx_thread(void *); extern int iscsi_target_rx_thread(void *); extern int iscsit_close_connection(struct iscsi_conn *); -extern int iscsit_close_session(struct iscsi_session *); +extern int iscsit_close_session(struct iscsi_session *, bool can_sleep); extern void iscsit_fail_session(struct iscsi_session *); extern void iscsit_stop_session(struct iscsi_session *, int, int); extern int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *, int); diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c index b4abd7b68e6d..102c9cbf59f3 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.c +++ b/drivers/target/iscsi/iscsi_target_erl0.c @@ -765,7 +765,7 @@ void iscsit_handle_time2retain_timeout(struct timer_list *t) iscsit_fill_cxn_timeout_err_stats(sess); spin_unlock_bh(&se_tpg->session_lock); - iscsit_close_session(sess); + iscsit_close_session(sess, false); } void iscsit_start_time2retain_handler(struct iscsi_session *sess) diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 45ba07c6ec27..9468b017b4a7 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -779,21 +779,22 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) } EXPORT_SYMBOL(iscsit_free_cmd); -int iscsit_check_session_usage_count(struct iscsi_session *sess) +bool iscsit_check_session_usage_count(struct iscsi_session *sess, + bool can_sleep) { spin_lock_bh(&sess->session_usage_lock); if (sess->session_usage_count != 0) { sess->session_waiting_on_uc = 1; spin_unlock_bh(&sess->session_usage_lock); - if (in_interrupt()) - return 2; + if (!can_sleep) + return true; wait_for_completion(&sess->session_waiting_on_uc_comp); - return 1; + return false; } spin_unlock_bh(&sess->session_usage_lock); - return 0; + return false; } void iscsit_dec_session_usage_count(struct iscsi_session *sess) diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 68e84803b0a1..8ee1c133a9b7 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -40,7 +40,7 @@ extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *); extern void iscsit_release_cmd(struct iscsi_cmd *); extern void __iscsit_free_cmd(struct iscsi_cmd *, bool); extern void iscsit_free_cmd(struct iscsi_cmd *, bool); -extern int iscsit_check_session_usage_count(struct iscsi_session *); +extern bool iscsit_check_session_usage_count(struct iscsi_session *sess, bool can_sleep); extern void iscsit_dec_session_usage_count(struct iscsi_session *); extern void iscsit_inc_session_usage_count(struct iscsi_session *); extern struct iscsi_conn *iscsit_get_conn_from_cid(struct iscsi_session *, u16); diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 6b72afee2f8b..5517c7dd5144 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -860,8 +860,6 @@ int core_alua_check_nonop_delay( { if (!(cmd->se_cmd_flags & SCF_ALUA_NON_OPTIMIZED)) return 0; - if (in_interrupt()) - return 0; /* * The ALUA Active/NonOptimized access state delay can be disabled * in via configfs with a value of zero diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index cce455929778..5a66854def95 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -267,7 +267,7 @@ fd_execute_rw_aio(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, struct fd_dev *fd_dev = FD_DEV(dev); struct file *file = fd_dev->fd_file; struct target_core_file_cmd *aio_cmd; - struct iov_iter iter = {}; + struct iov_iter iter; struct scatterlist *sg; ssize_t len = 0; int ret = 0, i; diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index fca4bd079d02..93ea17cbad79 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1313,12 +1313,32 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) " %u does not match SCSI CDB Length: %u for SAM Opcode:" " 0x%02x\n", cmd->se_tfo->fabric_name, cmd->data_length, size, cmd->t_task_cdb[0]); + /* + * For READ command for the overflow case keep the existing + * fabric provided ->data_length. Otherwise for the underflow + * case, reset ->data_length to the smaller SCSI expected data + * transfer length. + */ + if (size > cmd->data_length) { + cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; + cmd->residual_count = (size - cmd->data_length); + } else { + cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; + cmd->residual_count = (cmd->data_length - size); + /* + * Do not truncate ->data_length for WRITE command to + * dump all payload + */ + if (cmd->data_direction == DMA_FROM_DEVICE) { + cmd->data_length = size; + } + } if (cmd->data_direction == DMA_TO_DEVICE) { if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { pr_err_ratelimited("Rejecting underflow/overflow" " for WRITE data CDB\n"); - return TCM_INVALID_CDB_FIELD; + return TCM_INVALID_FIELD_IN_COMMAND_IU; } /* * Some fabric drivers like iscsi-target still expect to @@ -1332,31 +1352,6 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) return TCM_INVALID_CDB_FIELD; } } - /* - * Reject READ_* or WRITE_* with overflow/underflow for - * type SCF_SCSI_DATA_CDB. - */ - if (dev->dev_attrib.block_size != 512) { - pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" - " CDB on non 512-byte sector setup subsystem" - " plugin: %s\n", dev->transport->name); - /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ - return TCM_INVALID_CDB_FIELD; - } - /* - * For the overflow case keep the existing fabric provided - * ->data_length. Otherwise for the underflow case, reset - * ->data_length to the smaller SCSI expected data transfer - * length. - */ - if (size > cmd->data_length) { - cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; - cmd->residual_count = (size - cmd->data_length); - } else { - cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; - cmd->residual_count = (cmd->data_length - size); - cmd->data_length = size; - } } return target_check_max_data_sg_nents(cmd, dev, size); @@ -1512,17 +1507,14 @@ int transport_handle_cdb_direct( { sense_reason_t ret; + might_sleep(); + if (!cmd->se_lun) { dump_stack(); pr_err("cmd->se_lun is NULL\n"); return -EINVAL; } - if (in_interrupt()) { - dump_stack(); - pr_err("transport_generic_handle_cdb cannot be called" - " from interrupt context\n"); - return -EINVAL; - } + /* * Set TRANSPORT_NEW_CMD state and CMD_T_ACTIVE to ensure that * outstanding descriptors are handled correctly during shutdown via @@ -1613,10 +1605,11 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess sense_reason_t rc; int ret; + might_sleep(); + se_tpg = se_sess->se_tpg; BUG_ON(!se_tpg); BUG_ON(se_cmd->se_tfo || se_cmd->se_sess); - BUG_ON(in_interrupt()); if (flags & TARGET_SCF_USE_CPUID) se_cmd->se_cmd_flags |= SCF_USE_CPUID; @@ -1884,6 +1877,7 @@ void transport_generic_request_failure(struct se_cmd *cmd, case TCM_UNSUPPORTED_TARGET_DESC_TYPE_CODE: case TCM_TOO_MANY_SEGMENT_DESCS: case TCM_UNSUPPORTED_SEGMENT_DESC_TYPE_CODE: + case TCM_INVALID_FIELD_IN_COMMAND_IU: break; case TCM_OUT_OF_RESOURCES: cmd->scsi_status = SAM_STAT_TASK_SET_FULL; @@ -3210,6 +3204,11 @@ static const struct sense_detail sense_detail_table[] = { .asc = 0x55, .ascq = 0x04, /* INSUFFICIENT REGISTRATION RESOURCES */ }, + [TCM_INVALID_FIELD_IN_COMMAND_IU] = { + .key = ILLEGAL_REQUEST, + .asc = 0x0e, + .ascq = 0x03, /* INVALID FIELD IN COMMAND INFORMATION UNIT */ + }, }; /** |