On Wed, May 09, 2018 at 01:59:21PM -0700, Lee Duncan wrote:
> When a tape drive is exported via LIO using the
> pscsi module, a read that requests more bytes per block
> than the tape can supply returns an empty buffer. This
> is because the pscsi pass-through target module sees
> the "ILI" illegal length bit set and thinks there
> is no reason to return the data.
Please use the full line length available for commit messages..
> and the read succeeded. The layered tape driver then
> "does the right thing" when it gets such a response.
> - Moved ugly code from transport to pscsi module
probably wants and uptdate of the subject line as well.
> + * hack to check for TAPE device reads with
> + * FM/EOM/ILI set, so that we can get data
> + * back despite framework assumption that a
> + * check condition means there is no data
> + */
> + if ((sd->type == TYPE_TAPE) &&
> + (cmd->data_direction == DMA_FROM_DEVICE)) {
No need for the inner braces.
> + if ((req_sense[0] == 0xf0) && /* valid, fixed format
> */
> + (req_sense[2] & 0xe0) && /* FM, EOM, or ILI */
> + ((req_sense[2] & 0xf) == 0)) { /* key==NO_SENSE */
> + cmd->se_cmd_flags |= SCF_TREAT_READ_AS_NORMAL;
Same here.
> enum {
> diff --git a/drivers/target/target_core_transport.c
> b/drivers/target/target_core_transport.c
> index 74b646f165d4..56661a824266 100644
> --- a/drivers/target/target_core_transport.c
> +++ b/drivers/target/target_core_transport.c
> @@ -2192,6 +2192,11 @@ static void target_complete_ok_work(struct work_struct
> *work)
> if (atomic_read(&cmd->se_dev->dev_qf_count) != 0)
> schedule_work(&cmd->se_dev->qf_work_queue);
>
> + if (cmd->se_cmd_flags & SCF_TREAT_READ_AS_NORMAL) {
> + pr_debug("Tape FM/EOM/ILI status detected. Treating as OK\n");
> + goto treat_as_normal_read;
> + }
> +
> /*
> * Check if we need to send a sense buffer from
> * the struct se_cmd in question.
> @@ -2241,6 +2246,7 @@ static void target_complete_ok_work(struct work_struct
> *work)
> if (cmd->scsi_status)
> goto queue_status;
>
> +treat_as_normal_read:
> atomic_long_add(cmd->data_length,
> &cmd->se_lun->lun_stats.tx_data_octets);
> /*
The goto looks at least a little odd as it skips many things that
don't look realted. As far as I can tell what you want to skip is
mostly the SCF_TRANSPORT_TASK_SENSE check, which can be done with
an additional conditional. Do we also need to skip the scsi_status
check above? If yes it needs another conditional, and a good comment.