forked from luck/tmp_suning_uos_patched
scsi: target: core: Add cmd length set before cmd complete
[ Upstream commit 1c73e0c5e54d5f7d77f422a10b03ebe61eaed5ad ] TCM doesn't properly handle underflow case for service actions. One way to prevent it is to always complete command with target_complete_cmd_with_length(), however it requires access to data_sg, which is not always available. This change introduces target_set_cmd_data_length() function which allows to set command data length before completing it. Link: https://lore.kernel.org/r/20210209072202.41154-2-a.miloserdov@yadro.com Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com> Reviewed-by: Bodo Stroesser <bostroesser@gmail.com> Signed-off-by: Aleksandr Miloserdov <a.miloserdov@yadro.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
79b4fdd8b4
commit
17c2c52051
|
@ -873,11 +873,9 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
|
|||
}
|
||||
EXPORT_SYMBOL(target_complete_cmd);
|
||||
|
||||
void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length)
|
||||
void target_set_cmd_data_length(struct se_cmd *cmd, int length)
|
||||
{
|
||||
if ((scsi_status == SAM_STAT_GOOD ||
|
||||
cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) &&
|
||||
length < cmd->data_length) {
|
||||
if (length < cmd->data_length) {
|
||||
if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
|
||||
cmd->residual_count += cmd->data_length - length;
|
||||
} else {
|
||||
|
@ -887,6 +885,15 @@ void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int len
|
|||
|
||||
cmd->data_length = length;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(target_set_cmd_data_length);
|
||||
|
||||
void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length)
|
||||
{
|
||||
if (scsi_status == SAM_STAT_GOOD ||
|
||||
cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) {
|
||||
target_set_cmd_data_length(cmd, length);
|
||||
}
|
||||
|
||||
target_complete_cmd(cmd, scsi_status);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ int transport_backend_register(const struct target_backend_ops *);
|
|||
void target_backend_unregister(const struct target_backend_ops *);
|
||||
|
||||
void target_complete_cmd(struct se_cmd *, u8);
|
||||
void target_set_cmd_data_length(struct se_cmd *, int);
|
||||
void target_complete_cmd_with_length(struct se_cmd *, u8, int);
|
||||
|
||||
void transport_copy_sense_to_cmd(struct se_cmd *, unsigned char *);
|
||||
|
|
Loading…
Reference in New Issue
Block a user