On 2019/10/18 21:43, Martin K. Petersen wrote:
> Hannes,
>
>> The one thing which I patently don't like is the ambivalence between
>> DRIVER_SENSE and scsi_sense_valid(). What shall we do if only _one_
>> of them is set? IE what would be the correct way of action if
>> DRIVER_SENSE is not set, but we have a valid sense code? Or the other
>> way around?
> I agree, it's a mess.
>
> (Sorry, zhengbin, you opened a can of worms. This is some of our oldest
> and most arcane code in SCSI)
>
>> But more important, from a quick glance not all drivers set the
>> DRIVER_SENSE bit; so for things like hpsa or smartpqi the sense code is
>> never evaluated after this patchset.
> And yet we appear to have several code paths where sense evaluation is
> contingent on DRIVER_SENSE. So no matter what, behavior might
> change if we enforce consistent semantics. *sigh*
So what should we do to prevent unit-value access of sshdr?
1. still init sshdr in __scsi_execute?
@@ -255,6 +255,13 @@ int __scsi_execute(struct scsi_device *sdev, const
unsigned char *cmd,
struct scsi_request *rq;
int ret = DRIVER_ERROR << 24;
+ /*
+ * Zero-initialize sshdr for those callers that check the *sshdr
+ * contents even if no sense data is available.
+ */
+ if (sshdr)
+ memset(sshdr, 0, sizeof(struct scsi_sense_hdr));
+
req = blk_get_request(sdev->request_queue,
data_direction == DMA_TO_DEVICE ?
REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, BLK_MQ_REQ_PREEMPT);
2. init sshdr in callers of scsi_execute, instead of check the result of
scsi_execute and check
whether sshdr is valid? for example:
@@ -506,6 +506,7 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned
char *buffer,
put_unaligned_be32(len, &cmd[6]);
memset(buffer, 0, len);
+ memset(&sshdr, 0 ,sizeof(sshdr));
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
&sshdr, 30 * HZ, 3, NULL)
Besides, should sd_pr_command init sshdr?? cause sd_pr_command have checked
the result of scsi_execute
and check whether sshdr is valid.
3. get rid of DRIVER_* completely? even this, we should init sshdr first.
sshdr is just 8 bytes, init it does not affect performance
My advice is 2.
>
>> I _really_ would prefer to ditch the 'DRIVER_SENSE' bit, and rely on
>> scsi_sense_valid() only.
> I would really like to get rid of DRIVER_* completely. Except for
> DRIVER_SENSE, few are actually in use:
>
> DRIVER_OK: 0
> DRIVER_BUSY: 0
> DRIVER_SOFT: 0
> DRIVER_MEDIA: 0
> DRIVER_ERROR: 6
> DRIVER_INVALID: 4
> DRIVER_TIMEOUT: 1
> DRIVER_SENSE: 58
>
> Johannes: Whatever happened to your efforts at cleaning all this up? Do
> you have a patch series or a working tree we could use as starting
> point?
>