Re: [PATCH] scsi-sg: pass flag to inhibit setting LUN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dne 3.1.2014 21:10, Douglas Gilbert napsal(a):
> On 14-01-02 08:19 AM, Jiří Pinkava wrote:
>> Hi,
>>
>> This patch implements support for inhibiting setting LUN number
>> for SCSI custom command send via /dev/sgX with ioctl(.., SG_IO, ...)
>> call.
>>
>> This solves problems with some devices which claim support of
>> SCSI v1/v2, but for some special purposes use custom commands
>> which does not conform with standard message format.
>> (Like mine Pentax digital single-lens reflex camera)
>> It does not affect devices with SCSI v3 or latter.
>>
>> For this purpose was earlier introduced
>> SG_FLAG_LUN_INHIBIT / SG_FLAG_UNUSED_LUN_INHIBIT (glibc/kernel) flag,
>> but the implementation was lost in some earlier code refactor.
>>
>> The only possible issue I see is current implementation supports only
>> SG driver but there is few more code paths where the similar ioctl can
>> be invoked
>> (eg. anny SCSI device?). I'm not sure about, feel free to say anything
>> about it.
>
> Hi,
> SG_FLAG_LUN_INHIBIT was added to the sg driver around 15
> years ago. The code to centralize the masking in scsi.c
> and remove the "LUN inhibit" capability arrived about
> 10 years ago. A handful of people have complained about
> it since. An you are the first to do something about it!
>
> I have a few comments about the code (see below) but the
> logic seems okay to me. That said I would be very surprised
> if this is allowed back in the kernel. If you manage to do
> that then I'll be studying your technique (because many of my
> patches to the sg driver are not accepted).
>
> So you can takes that as an "ack" with comments and good luck.
> I'll let others judge.
>
>> ---
>>   drivers/scsi/scsi.c       | 3 ++-
>>   drivers/scsi/sg.c         | 3 +++
>>   include/linux/blk_types.h | 2 ++
>>   3 files changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
>> index fe0bcb1..f6d5fc9 100644
>> --- a/drivers/scsi/scsi.c
>> +++ b/drivers/scsi/scsi.c
>> @@ -693,7 +693,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
>>        * If SCSI-2 or lower, store the LUN value in cmnd.
>>        */
>>       if (cmd->device->scsi_level <= SCSI_2 &&
>> -        cmd->device->scsi_level != SCSI_UNKNOWN) {
>> +        cmd->device->scsi_level != SCSI_UNKNOWN &&
>> +        !(cmd->request->cmd_flags & REQ_LUN_INHIBIT)) {
>>           cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) |
>>                      (cmd->device->lun << 5 & 0xe0);
>>       }
>
> The above being time sensitive code I was thinking a switch
> might make it clearer and give the compiler more chances to
> optimize:
>       switch(cmd->device->scsi_level) {
>       case SCSI_2:
>       case SCSI_1_CCS:
>       case SCSI_1:
>               if (!(cmd->request->cmd_flags & REQ_LUN_INHIBIT)) {
>                       cmd->cmnd[1] = (cmd->cmnd[1] & 0x1f) |
>                                      (cmd->device->lun << 5 & 0xe0);
>               }
>               break;
>       default:
>               ;
>       }
>
> Hmm, can a switch's default be made "likely"?

In switch can be used only __branch_check__ (E, C) or
__builtin_expect(E, C), which
have too many '_' in name and I'm too afraid to use them.

switch (__builtin_expect(var, const)) {
...

if there is such a pressure for speed, unlikely(cmd->device->scsi_level
<= SCSI_2)
might be used, but i does not have statistics about how much modern
high-speed devices report itself as scsi_level <= SCSI_2 or scsi_level
== SCSI_UNKNOWN.
(suppose the rate is pretty low).

The switch solution look more elegant.

>
> More generally folks, with SAS SSDs available that can read at
> 1100 MB/sec we may want to spend time looking at the fast
> paths through the SCSI subsystem.
>
>
>> diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
>> index df5e961..8e09015 100644
>> --- a/drivers/scsi/sg.c
>> +++ b/drivers/scsi/sg.c
>> @@ -1663,6 +1663,9 @@ static int sg_start_req(Sg_request *srp, unsigned
>> char *cmd)
>>       rq->sense = srp->sense_b;
>>       rq->retries = SG_DEFAULT_RETRIES;
>>
>> +    if (hp->flags & SG_FLAG_UNUSED_LUN_INHIBIT)
>> +        rq->cmd_flags |=  REQ_LUN_INHIBIT;
>> +
>>       if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))
>>           return 0;
>>
>> diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
>> index 238ef0e..35d436b 100644
>> --- a/include/linux/blk_types.h
>> +++ b/include/linux/blk_types.h
>> @@ -178,6 +178,7 @@ enum rq_flag_bits {
>>       __REQ_MIXED_MERGE,    /* merge of different types, fail
>> separately */
>>       __REQ_KERNEL,         /* direct IO to kernel pages */
>>       __REQ_PM,        /* runtime pm request */
>> +    __REQ_LUN_INHIBIT,    /* pass through for
>> SG_FLAG_UNUSED_LUN_INHIBIT flag */
>>       __REQ_END,        /* last of chain of requests */
>>       __REQ_NR_BITS,        /* stops here */
>>   };
>> @@ -230,6 +231,7 @@ enum rq_flag_bits {
>>   #define REQ_SECURE        (1ULL << __REQ_SECURE)
>>   #define REQ_KERNEL        (1ULL << __REQ_KERNEL)
>>   #define REQ_PM            (1ULL << __REQ_PM)
>> +#define REQ_LUN_INHIBIT    (1ULL << __REQ_LUN_INHIBIT)
>>   #define REQ_END            (1ULL << __REQ_END)
>>
>>   #endif /* __LINUX_BLK_TYPES_H */
>>
>
> And I think the SG_FLAG_LUN_INHIBIT define should be re-instated
> to sg.h . For backward compatibility (for the last 10 years)
> please leave the SG_FLAG_UNUSED_LUN_INHIBIT define there. Both
> defines should have the same value.
>
> Doug Gilbert
>

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux