Re: [PATCH] scsi: Make scsi_vpd_lun_id() able to use T10 vendor ID based designators

2016-05-05 Thread Hannes Reinecke
On 05/05/2016 05:50 AM, Paul Mackerras wrote:
> On Wed, May 04, 2016 at 12:04:16PM +0200, Hannes Reinecke wrote:
>> On 05/04/2016 08:58 AM, Paul Mackerras wrote:
>>> This adds code to scsi_vpd_lun_id() to enable it to use T10 vendor ID
>>> based designators.  This is needed to allow alua to work on disks that
>>> don't have any designators of type 2, 3 or 8.  Commit 0047220c6c36
>>> ("scsi_dh_alua: use unique device id", 2016-02-19) added a requirement
>>> that alua can only be used on disks for which scsi_vpd_lun_id() can
>>> produce an identifying string.
>>>
>>> Signed-off-by: Paul Mackerras 
>>> ---
>>>  drivers/scsi/scsi_lib.c |   14 ++
>>>  1 file changed, 14 insertions(+)
>>>
>>> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
>>> index 8106515..f4f69cc 100644
>>> --- a/drivers/scsi/scsi_lib.c
>>> +++ b/drivers/scsi/scsi_lib.c
>>> @@ -3214,6 +3214,20 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char 
>>> *id, size_t id_len)
>>> goto next_desig;
>>>  
>>> switch (d[1] & 0xf) {
>>> +   case 0x1:
>>> +   /* T10 vendor ID */
>>> +   if (cur_id_size > d[3])
>>> +   break;
>>> +   /* Prefer EUI-64 or NAA IEEE Registered Extended */
>>> +   if ((cur_id_type == 0x2 || cur_id_type == 0x3) &&
>>> +   cur_id_size == d[3])
>>> +   break;
>>> +   cur_id_size = d[3];
>>> +   cur_id_str = d + 4;
>>> +   cur_id_type = d[1] & 0xf;
>>> +   id_size = snprintf(id, id_len, "%*phN", cur_id_size,
>>> +  cur_id_str);
>>> +   break;
>>> case 0x2:
>>> /* EUI-64 */
>>> if (cur_id_size > d[3])
>>>
>> Nearly.
>> The thing is, a T-10 vendor specific ID is _supposed_ to be an ASCII
>> string. So I'd rather have it decoded as such.
> 
> Do we need to defend against non-printing characters in the string?
> 
I really would like to stick to ASCII output here, as most vendors put a
meaningful string in here.
Those who don't we should be going with the '.' normal method and print
a dot '.' instead.
(Can't we fix up snprintf do do it for us? Would be soo cool ...)

>> And we're missing decoding for 'vendor-specific' ID, too.
> 
> There's no guarantee that this would be ASCII, right?  So would you
> print it in hex?
> 
Yes, that's the plan here.

> Also, is there a preference between these types?  For example, is an
> 8-byte EUI-64 preferable to a vendor-specific ID of any length?
> 
Yes. I'd treat T10 vendor ID descriptors with the lowest preference
(irrespective of the length), eclipsed (sic) only by the truly vendor
specific ones.
And actually I would make the vendor-specific decoding the default
entry, too, as we might come across some other descriptors which we
cannot decode (yet). And by having a default method for decoding we
ensure to always be able to come up with an ALUA identification.
Otherwise we might end up in the same situation as we're in now.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke   zSeries & Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] scsi: Make scsi_vpd_lun_id() able to use T10 vendor ID based designators

2016-05-05 Thread Paul Mackerras
On Thu, May 05, 2016 at 10:01:13AM +0200, Hannes Reinecke wrote:
> On 05/05/2016 05:50 AM, Paul Mackerras wrote:
> > On Wed, May 04, 2016 at 12:04:16PM +0200, Hannes Reinecke wrote:
...
> >> Nearly.
> >> The thing is, a T-10 vendor specific ID is _supposed_ to be an ASCII
> >> string. So I'd rather have it decoded as such.
> > 
> > Do we need to defend against non-printing characters in the string?
> > 
> I really would like to stick to ASCII output here, as most vendors put a
> meaningful string in here.
> Those who don't we should be going with the '.' normal method and print
> a dot '.' instead.
> (Can't we fix up snprintf do do it for us? Would be soo cool ...)
> 
> >> And we're missing decoding for 'vendor-specific' ID, too.
> > 
> > There's no guarantee that this would be ASCII, right?  So would you
> > print it in hex?
> > 
> Yes, that's the plan here.
> 
> > Also, is there a preference between these types?  For example, is an
> > 8-byte EUI-64 preferable to a vendor-specific ID of any length?
> > 
> Yes. I'd treat T10 vendor ID descriptors with the lowest preference
> (irrespective of the length), eclipsed (sic) only by the truly vendor
> specific ones.

Well, the disks on my system all have the same vendor-specific ID,
unfortunately -- a '0' followed by 19 spaces.  Here are the
designators for all the disks on my system:

scsi 0:2:0:0: 02 01 00 20 'IBM IPR-0   5EC4AB20'
scsi 0:2:0:0: 02 00 00 14 '0   '
scsi 0:2:1:0: 02 01 00 20 'IBM IPR-0   5EC28C80'
scsi 0:2:1:0: 02 00 00 14 '0   '
scsi 0:2:2:0: 02 01 00 20 'IBM IPR-0   5EC28C60'
scsi 0:2:2:0: 02 00 00 14 '0   '
scsi 0:2:3:0: 02 01 00 20 'IBM IPR-0   5EC28C40'
scsi 0:2:3:0: 02 00 00 14 '0   '
scsi 0:2:4:0: 02 01 00 20 'IBM IPR-0   5EC28C20'
scsi 0:2:4:0: 02 00 00 14 '0   '
scsi 0:2:5:0: 02 01 00 20 'IBM IPR-0   5EC28CC0'
scsi 0:2:5:0: 02 00 00 14 '0   '
scsi 0:2:6:0: 02 01 00 20 'IBM IPR-0   5EC28CA0'
scsi 0:2:6:0: 02 00 00 14 '0   '

> And actually I would make the vendor-specific decoding the default
> entry, too, as we might come across some other descriptors which we
> cannot decode (yet). And by having a default method for decoding we
> ensure to always be able to come up with an ALUA identification.
> Otherwise we might end up in the same situation as we're in now.

What would happen if we pick a designator which is not unique across
different disks?  Would we think that they were all the same disk?

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


Re: [PATCH] Fix a bdi reregistration race, v3

2016-05-05 Thread Bart Van Assche

On 03/28/2016 02:29 PM, Bart Van Assche wrote:

Avoid that the sd driver registers a BDI device with a name that
is still in use. This patch avoids that the following warning gets
triggered:

[ ... ]


(replying to my own e-mail)

If anyone could review this patch that would be very welcome.

Thanks,

Bart.

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


Re: [PATCH] Fix a bdi reregistration race, v3

2016-05-05 Thread Joe Lawrence
On 05/05/2016 03:58 PM, Bart Van Assche wrote:
> On 03/28/2016 02:29 PM, Bart Van Assche wrote:
>> Avoid that the sd driver registers a BDI device with a name that
>> is still in use. This patch avoids that the following warning gets
>> triggered:
>>
>> [ ... ]
> 
> (replying to my own e-mail)
> 
> If anyone could review this patch that would be very welcome.

Hi Bart,

I *think* I may be hitting this same problem running some tests here at Stratus 
-- I've got slub_debugging and other kernel debugging turned on while 
repeatedly hotplugging controllers at various timings during probe.  It takes 
hours to hit, but I've seen it twice in the past week.  I've got some other 
testing on my plate at the moment, but when I get a chance I can give your v3 a 
spin.

Here's an example (sorry for the wide width) ...

[ cut here ]
WARNING: CPU: 5 PID: 30702 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x64/0x80
sysfs: cannot create duplicate filename '/devices/virtual/bdi/65:0'
Modules linked in: btrfs xor raid6_pq msdos ext4 jbd2 mbcache matroxfb(OE) 
ccmod(POE) ftmod(OE) videosw(OE) ipmi_devintf fuse xt_CHECKSUM ipt_MASQUERADE 
nf_nat_masquerade_ipv4 tun ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT 
nf_reject_ipv4 xt_conntrack bonding ebtable_nat ebtable_broute bridge stp llc 
ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 
nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter 
ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat 
nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter vfat 
fat x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul 
crc32_pclmul ghash_clmulni_intel aesni_intel glue_helper lrw gf128mul 
ablk_helper cryptd dm_service_time pcspkr ses enclosure sg wmi nfsd auth_rpcgss 
nfs_acl lockd grace sunrpc dm_multipath ip_tables xfs libcrc32c raid1 sr_mod 
cdrom crc32c_intel qla2xxx(OE) scsi_transport_fc ixgbe(OE) mdio igb(OE) ptp 
pps_core mpt3sas(OE) 
raid_class i2c_algo_bit sra_sense(OE) i2c_core sd_mod(OE) scsi_transport_sas 
dca scsi_hbas(OE) fjes ipmi_msghandler usb_storage dm_mirror dm_region_hash 
dm_log dm_mod [last unloaded: ipmi_devintf]
CPU: 5 PID: 30702 Comm: kworker/u97:7 Tainted: PW  OE   4.6.0-rc6+ #37
Hardware name: Stratus ftServer 6800/G7LYY, BIOS BIOS Version 8.1:64 02/03/2016
Workqueue: events_unbound async_run_entry_fn
 0286 e136f6f8 88038ae03a50 8134359f
 88038ae03aa0  88038ae03a90 8108af31
 001f5bdb0398 880067e0e7e8 88058f92def0 88084bd2c008
Call Trace:
 [] dump_stack+0x63/0x84
 [] __warn+0xd1/0xf0
 [] warn_slowpath_fmt+0x5f/0x80
 [] sysfs_warn_dup+0x64/0x80
 [] sysfs_create_dir_ns+0x7e/0x90
 [] kobject_add_internal+0xaa/0x320
 [] ? device_private_init+0x23/0x70
 [] kobject_add+0x75/0xd0
 [] ? mutex_lock+0x12/0x2f
 [] device_add+0x125/0x610
 [] device_create_groups_vargs+0xd8/0x100
 [] device_create_vargs+0x1c/0x20
 [] bdi_register+0x8c/0x180
 [] bdi_register_dev+0x27/0x30
 [] add_disk+0x17f/0x4a0
 [] ? update_autosuspend+0x55/0x60
 [] ? __pm_runtime_use_autosuspend+0x54/0x70
 [] sd_probe_async+0x115/0x1d0 [sd_mod]
 [] async_run_entry_fn+0x4a/0x140
 [] process_one_work+0x16e/0x420
 [] worker_thread+0x125/0x4b0
 [] ? __schedule+0x2ad/0x8a0
 [] ? rescuer_thread+0x380/0x380
 [] kthread+0xd8/0xf0
 [] ret_from_fork+0x22/0x40
 [] ? kthread_park+0x60/0x60
---[ end trace 353add4e78cb2a75 ]---
[ cut here ]
WARNING: CPU: 5 PID: 30702 at lib/kobject.c:240 kobject_add_internal+0x262/0x320
kobject_add_internal failed for 65:0 with -EEXIST, don't try to register things 
with the same name in the same directory.
Modules linked in: btrfs xor raid6_pq msdos ext4 jbd2 mbcache matroxfb(OE) 
ccmod(POE) ftmod(OE) videosw(OE) ipmi_devintf fuse xt_CHECKSUM ipt_MASQUERADE 
nf_nat_masquerade_ipv4 tun ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT 
nf_reject_ipv4 xt_conntrack bonding ebtable_nat ebtable_broute bridge stp llc 
ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 
nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter 
ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat 
nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter vfat 
fat x86_pkg_temp_thermal intel_powerclamp coretemp crct10dif_pclmul 
crc32_pclmul ghash_clmulni_intel aesni_intel glue_helper lrw gf128mul 
ablk_helper cryptd dm_service_time pcspkr ses enclosure sg wmi nfsd auth_rpcgss 
nfs_acl lockd grace sunrpc dm_multipath ip_tables xfs libcrc32c raid1 sr_mod 
cdrom crc32c_intel qla2xxx(OE) scsi_transport_fc ixgbe(OE) mdio igb(OE) ptp 
pps_core mpt3sas(OE) 
raid_class i2c_algo_bit sra_sense(OE) i2c_core sd_mod(OE) scsi_transport_sas 
dca scsi_hbas(OE) fjes ipmi_msghandler usb_storage dm_mirror dm_region_hash 
dm_log dm_mod [last unloaded: ipmi_devintf]
CPU: 5 PID: 30702 Comm: kworker/u97:7 Tainted: PW  OE   4.

[PATCH] target: need_to_release is always false, remove redundant check and kfree

2016-05-05 Thread Colin King
From: Colin Ian King 

The removal the #ifdef'd code on CONFIG_ARCH_HAS_SG_CHAIN in
commit 02c4de53add1b79 ("target/rd: always chain S/G list")
removed the setting of need_to_release to true, so we are now left
with need_to_release always being false and hence the conditional
kfree is never reached.  Clean up the dead code by removing need_to_release
and the conditional kfree.

Signed-off-by: Colin Ian King 
---
 drivers/target/target_core_rd.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index 47a833f..24b36fd 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -403,7 +403,6 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, 
bool is_read)
struct se_device *se_dev = cmd->se_dev;
struct rd_dev *dev = RD_DEV(se_dev);
struct rd_dev_sg_table *prot_table;
-   bool need_to_release = false;
struct scatterlist *prot_sg;
u32 sectors = cmd->data_length / se_dev->dev_attrib.block_size;
u32 prot_offset, prot_page;
@@ -432,9 +431,6 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, 
bool is_read)
if (!rc)
sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset);
 
-   if (need_to_release)
-   kfree(prot_sg);
-
return rc;
 }
 
-- 
2.8.1

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


Re: [PATCH 1/1] cxlflash: Fix to resolve dead-lock during EEH recovery

2016-05-05 Thread Martin K. Petersen
> "Uma" == Uma Krishnan  writes:

Uma> When a cxlflash adapter goes into EEH recovery and multiple
Uma> processes (each having established its own context) are active, the
Uma> EEH recovery can hang if the processes attempt to recover in
Uma> parallel. The symptom logged after a couple of minutes is:

Applied to 4.7/scsi-queue.

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] megaraid: Downgrade two success messages to info

2016-05-05 Thread Martin K. Petersen
> "Andy" == Andy Lutomirski  writes:

Andy> I actually read the error messages in my logs, and successful
Andy> initialization is not an error.

Andy> Arguably these log lines could be deleted entirely.

Applied to 4.7/scsi-queue.

Thanks!

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH resend v2] [SCSI] bfa: fix bfa_fcb_itnim_alloc() error handling

2016-05-05 Thread Martin K. Petersen
> "Dan" == Dan Carpenter  writes:

Dan> The caller assumes that "itnim" is NULL on error and non-NULL on
Dan> success but really "itnim" is uninitialized on error.  This
Dan> function should just use normal error handling where it returns
Dan> zero on success and negative on failure.

Anil, please review:

https://patchwork.kernel.org/patch/8820751/

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2.5 3/6] scsi_debug: add multiple queue support

2016-05-05 Thread Douglas Gilbert

On 2016-05-04 06:32 PM, Bart Van Assche wrote:

On 04/30/2016 07:44 PM, Douglas Gilbert wrote:

+static struct sdebug_queue *get_queue(void)
+{
+struct sdebug_queue *sqp = sdebug_q_arr;
+
+return sqp + (raw_smp_processor_id() % submit_queues);
+}


Does this function have the same purpose as blk_mq_map_queue()? If so, why has
this function been introduced instead of using blk_mq_map_queue()?


No, it is copied from drivers/block/null_blk.c, the nullb_to_queue()
function. scsi_lib.c seems to be the only user of blk_mq_map_queue().


@@ -5001,6 +5158,10 @@ static int scsi_debug_queuecommand(struct Scsi_Host
*shost,
  bool has_wlun_rl;

  scsi_set_resid(scp, 0);
+if (sdebug_statistics) {
+sqp = get_queue();
+atomic_inc(&sqp->cmnd_count);
+}


Why does scsi_debug_queuecommand() call get_queue() instead of
blk_mq_unique_tag() and blk_mq_unique_tag_to_hwq() which is what other scsi-mq
drivers do?


Okay I have switched to using:
u32 tag = blk_mq_unique_tag(cmnd->request);
u16 hwq = blk_mq_unique_tag_to_hwq(tag);
return sqp + hwq;

and as far as I can tell it works just as well as:
return sqp + (raw_smp_processor_id() % submit_queues);


Is the role of the sqp->cmnd_count counter identical to that of
blk_mq_hw_ctx.queued? If so, can sqp->cmnd_count be left out and can
blk_mq_hw_ctx.queued be used instead?


Not quite, it counts commands in, some of which may get
responded to in the same thread (e.g. when a SCSI illegal request
type error is being reported). But it is very close to my
"completions" count.

So I'll move those counters back into file scope which simplifies
scsi_debug's logic. The cmnd_counter is used in the injection of
pseudo errors "every_nth" command. Can blk_mq_hw_ctx.queued be
viewed from the user space?


@@ -5168,6 +5328,16 @@ static int sdebug_driver_probe(struct device * dev)
+if (sdebug_mq_available && (submit_queues > 1))
+hpnt->nr_hw_queues = submit_queues;


There is already a submit_queues < 1 check in scsi_debug_init(). Is the
submit_queues > 1 check in sdebug_driver_probe() needed?


I noticed that the other (2) scsi mq LLDs take care only to set
hpnt->nr_hw_queues when the submit_queues > 1 .

Tomorrow I plan to issue a "v3" of this patchset.

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


Re: [PATCH v2.5 3/6] scsi_debug: add multiple queue support

2016-05-05 Thread Bart Van Assche

On 05/05/16 20:47, Douglas Gilbert wrote:

On 2016-05-04 06:32 PM, Bart Van Assche wrote:

On 04/30/2016 07:44 PM, Douglas Gilbert wrote:

+static struct sdebug_queue *get_queue(void)
+{
+struct sdebug_queue *sqp = sdebug_q_arr;
+
+return sqp + (raw_smp_processor_id() % submit_queues);
+}


Does this function have the same purpose as blk_mq_map_queue()? If so,
why has
this function been introduced instead of using blk_mq_map_queue()?


No, it is copied from drivers/block/null_blk.c, the nullb_to_queue()
function. scsi_lib.c seems to be the only user of blk_mq_map_queue().


@@ -5001,6 +5158,10 @@ static int scsi_debug_queuecommand(struct
Scsi_Host
*shost,
  bool has_wlun_rl;

  scsi_set_resid(scp, 0);
+if (sdebug_statistics) {
+sqp = get_queue();
+atomic_inc(&sqp->cmnd_count);
+}


Why does scsi_debug_queuecommand() call get_queue() instead of
blk_mq_unique_tag() and blk_mq_unique_tag_to_hwq() which is what other
scsi-mq
drivers do?


Okay I have switched to using:
 u32 tag = blk_mq_unique_tag(cmnd->request);
 u16 hwq = blk_mq_unique_tag_to_hwq(tag);
 return sqp + hwq;

and as far as I can tell it works just as well as:
 return sqp + (raw_smp_processor_id() % submit_queues);


Thanks for the feedback. I was not yet aware that null_blk also follows 
this approach. Apparently null_blk has its own prep function and that 
prep function needs access to the submit queue. Maybe that is why 
null_blk has its own submit queue selection function. However, I'd like 
to see that kind of code being moved from the null_blk driver into the 
blk-mq core.



Is the role of the sqp->cmnd_count counter identical to that of
blk_mq_hw_ctx.queued? If so, can sqp->cmnd_count be left out and can
blk_mq_hw_ctx.queued be used instead?


Not quite, it counts commands in, some of which may get
responded to in the same thread (e.g. when a SCSI illegal request
type error is being reported). But it is very close to my
"completions" count.

So I'll move those counters back into file scope which simplifies
scsi_debug's logic. The cmnd_counter is used in the injection of
pseudo errors "every_nth" command. Can blk_mq_hw_ctx.queued be
viewed from the user space?


As far as I can see, yes. From block/blk-mq-sysfs.c:

static ssize_t blk_mq_hw_sysfs_queued_show(struct blk_mq_hw_ctx *hctx,
   char *page)
{
return sprintf(page, "%lu\n", hctx->queued);
}


@@ -5168,6 +5328,16 @@ static int sdebug_driver_probe(struct device *
dev)
+if (sdebug_mq_available && (submit_queues > 1))
+hpnt->nr_hw_queues = submit_queues;


There is already a submit_queues < 1 check in scsi_debug_init(). Is the
submit_queues > 1 check in sdebug_driver_probe() needed?


I noticed that the other (2) scsi mq LLDs take care only to set
hpnt->nr_hw_queues when the submit_queues > 1 .


You might have overlooked the ib_srp driver. That driver is a SCSI LLD 
to which support for multiple hardware queues was added before it was 
added to the lpfc and virtio_scsi drivers.


I haven't found any code in any of these three drivers that only 
modifies nr_hw_queues if submit_queues > 1 ? Anyway, this is a detail 
and something I do not consider important.


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


[PATCH v3 0/6] scsi_debug: multiple queue support and cleanup

2016-05-05 Thread Douglas Gilbert
Changes since v2.5
  - rework the 'add multiple queue support' patch based on
reviewers' comments to more closely follow the scsi/block mq
template

Changes since original version:
  - reduce resp_report_luns to reporting 256 LUNs (0 to 255)
using address_method=0 which is single level peripheral
device addressing method. Reviewer would like further
address_methods support which will be presented as a
separate patch

Primary reason for this patch series is to add multi queue support
modelled on the null_blk driver. Incorporate REPORT LUNS patch from
Tomas Winkler sent in Febrary 2015; trim to a maximum of 256 LUNs
(0 to 255) per target. Add parameter that permits LU names to use
UUIDs (spc5r08.pdf).

The original patch set was made up of 12 patches, the first 7 of
which have already been accepted with minor edits. This patch set
(and "v2.5" before it) represent the second half of the original patch
set. So this patch set is based on the current SCSI maintainers'
repositories. For those who want to try this patch set on lk 4.5
or the linux-stable tree, this patch should be applied before
this series:
   http://sg.danny.cz/sg/p/sdebug_mq_1st_half.patch

Douglas Gilbert (6):
  scsi_debug: use pdt constants
  scsi_debug: rework resp_report_luns
  scsi_debug: add multiple queue support
  scsi_debug: vpd and mode page work
  scsi_debug: uuid for lu name
  scsi_debug: use locally assigned naa

 drivers/scsi/scsi_debug.c | 1156 -
 1 file changed, 730 insertions(+), 426 deletions(-)

-- 
2.7.4

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


[PATCH v3 1/6] scsi_debug: use pdt constants

2016-05-05 Thread Douglas Gilbert
Use TYPE_* constants for SCSI peripheral device types instead
of numbers. Further cleanups requested by checkpatch.pl .

Reviewed-by: Hannes Reinecke 
Reviewed-by: Bart Van Assche 
Signed-off-by: Douglas Gilbert 
---
 drivers/scsi/scsi_debug.c | 86 +--
 1 file changed, 45 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 6b2d006..fc0246c 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -59,8 +59,8 @@
 #include "scsi_logging.h"
 
 /* make sure inq_product_rev string corresponds to this version */
-#define SCSI_DEBUG_VERSION "1.86"
-static const char *sdebug_version_date = "20160422";
+#define SDEBUG_VERSION "1.86"
+static const char *sdebug_version_date = "20160430";
 
 #define MY_NAME "scsi_debug"
 
@@ -123,7 +123,7 @@ static const char *sdebug_version_date = "20160422";
 #define DEF_OPTS   0
 #define DEF_OPT_BLKS 1024
 #define DEF_PHYSBLK_EXP 0
-#define DEF_PTYPE   0
+#define DEF_PTYPE   TYPE_DISK
 #define DEF_REMOVABLE false
 #define DEF_SCSI_LEVEL   6/* INQUIRY, byte2 [6->SPC-4] */
 #define DEF_SECTOR_SIZE 512
@@ -137,6 +137,8 @@ static const char *sdebug_version_date = "20160422";
 #define DEF_STRICT 0
 #define JDELAY_OVERRIDDEN -
 
+#define SDEBUG_LUN_0_VAL 0
+
 /* bit mask values for sdebug_opts */
 #define SDEBUG_OPT_NOISE   1
 #define SDEBUG_OPT_MEDIUM_ERR  2
@@ -232,7 +234,7 @@ static const char *sdebug_version_date = "20160422";
 
 #define SDEBUG_MAX_PARTS 4
 
-#define SCSI_DEBUG_MAX_CMD_LEN 32
+#define SDEBUG_MAX_CMD_LEN 32
 
 
 struct sdebug_dev_info {
@@ -278,8 +280,8 @@ struct sdebug_scmd_extra_t {
 };
 
 struct opcode_info_t {
-   u8 num_attached;/* 0 if this is it (i.e. a leaf); use 0xff
-* for terminating element */
+   u8 num_attached;/* 0 if this is it (i.e. a leaf); use 0xff */
+   /* for terminating element */
u8 opcode;  /* if num_attached > 0, preferred */
u16 sa; /* service action */
u32 flags;  /* OR-ed set of SDEB_F_* */
@@ -571,7 +573,7 @@ static int sdebug_num_tgts = DEF_NUM_TGTS; /* targets per 
host */
 static int sdebug_opt_blks = DEF_OPT_BLKS;
 static int sdebug_opts = DEF_OPTS;
 static int sdebug_physblk_exp = DEF_PHYSBLK_EXP;
-static int sdebug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */
+static int sdebug_ptype = DEF_PTYPE; /* SCSI peripheral device type */
 static int sdebug_scsi_level = DEF_SCSI_LEVEL;
 static int sdebug_sector_size = DEF_SECTOR_SIZE;
 static int sdebug_virtual_gb = DEF_VIRTUAL_GB;
@@ -649,7 +651,7 @@ static const int device_qfull_result =
(DID_OK << 16) | (COMMAND_COMPLETE << 8) | SAM_STAT_TASK_SET_FULL;
 
 
-static unsigned int scsi_debug_lbp(void)
+static inline unsigned int scsi_debug_lbp(void)
 {
return 0 == sdebug_fake_rw &&
(sdebug_lbpu || sdebug_lbpws || sdebug_lbpws10);
@@ -825,7 +827,8 @@ static int make_ua(struct scsi_cmnd *scp, struct 
sdebug_dev_info *devip)
break;
case SDEBUG_UA_MICROCODE_CHANGED:
mk_sense_buffer(scp, UNIT_ATTENTION,
-   TARGET_CHANGED_ASC, MICROCODE_CHANGED_ASCQ);
+   TARGET_CHANGED_ASC,
+   MICROCODE_CHANGED_ASCQ);
if (sdebug_verbose)
cp = "microcode has been changed";
break;
@@ -1225,11 +1228,11 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct 
sdebug_dev_info *devip)
arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC);
if (! arr)
return DID_REQUEUE << 16;
-   have_wlun = (scp->device->lun == SCSI_W_LUN_REPORT_LUNS);
+   have_wlun = scsi_is_wlun(scp->device->lun);
if (have_wlun)
-   pq_pdt = 0x1e;  /* present, wlun */
-   else if (sdebug_no_lun_0 && (0 == devip->lun))
-   pq_pdt = 0x7f;  /* not present, no device type */
+   pq_pdt = TYPE_WLUN; /* present, wlun */
+   else if (sdebug_no_lun_0 && (devip->lun == SDEBUG_LUN_0_VAL))
+   pq_pdt = 0x7f;  /* not present, PQ=3, PDT=0x1f */
else
pq_pdt = (sdebug_ptype & 0x1f);
arr[0] = pq_pdt;
@@ -1244,7 +1247,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct 
sdebug_dev_info *devip)

port_group_id = (((host_no + 1) & 0x7f) << 8) +
(devip->channel & 0x7f);
-   if (0 == sdebug_vpd_use_hostno)
+   if (sdebug_vpd_use_hostno == 0)
host_no = 0;
lu_id_num = have_wlun ? -1 : (((host_no + 1) * 2000) +
(devip->target * 1000) + devip->lun);
@@ -1333,7 +1336,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct 
sde

[PATCH v3 3/6] scsi_debug: add multiple queue support

2016-05-05 Thread Douglas Gilbert
Add submit_queue parameter (minimum and default: 1; maximum:
nr_cpu_ids) that controls how many queues are built, each with
their own lock and in_use bit vector. Add statistics parameter
which is default off.

Signed-off-by: Douglas Gilbert 
---
 drivers/scsi/scsi_debug.c | 702 +-
 1 file changed, 446 insertions(+), 256 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index e97ddf0..2ee55d5 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -135,6 +135,8 @@ static const char *sdebug_version_date = "20160430";
 #define DEF_VPD_USE_HOSTNO 1
 #define DEF_WRITESAME_LENGTH 0x
 #define DEF_STRICT 0
+#define DEF_STATISTICS false
+#define DEF_SUBMIT_QUEUES 1
 #define JDELAY_OVERRIDDEN -
 
 #define SDEBUG_LUN_0_VAL 0
@@ -201,20 +203,17 @@ static const char *sdebug_version_date = "20160430";
  * or "peripheral device" addressing (value 0) */
 #define SAM2_LUN_ADDRESS_METHOD 0
 
-/* SCSI_DEBUG_CANQUEUE is the maximum number of commands that can be queued
- * (for response) at one time. Can be reduced by max_queue option. Command
- * responses are not queued when jdelay=0 and ndelay=0. The per-device
- * DEF_CMD_PER_LUN can be changed via sysfs:
- * /sys/class/scsi_device//device/queue_depth but cannot exceed
- * SCSI_DEBUG_CANQUEUE. */
-#define SCSI_DEBUG_CANQUEUE_WORDS  9   /* a WORD is bits in a long */
-#define SCSI_DEBUG_CANQUEUE  (SCSI_DEBUG_CANQUEUE_WORDS * BITS_PER_LONG)
+/* SDEBUG_CANQUEUE is the maximum number of commands that can be queued
+ * (for response) per submit queue at one time. Can be reduced by max_queue
+ * option. Command responses are not queued when jdelay=0 and ndelay=0. The
+ * per-device DEF_CMD_PER_LUN can be changed via sysfs:
+ * /sys/class/scsi_device//device/queue_depth
+ * but cannot exceed SDEBUG_CANQUEUE .
+ */
+#define SDEBUG_CANQUEUE_WORDS  3   /* a WORD is bits in a long */
+#define SDEBUG_CANQUEUE  (SDEBUG_CANQUEUE_WORDS * BITS_PER_LONG)
 #define DEF_CMD_PER_LUN  255
 
-#if DEF_CMD_PER_LUN > SCSI_DEBUG_CANQUEUE
-#warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE"
-#endif
-
 #define F_D_IN 1
 #define F_D_OUT2
 #define F_D_OUT_MAYBE  4   /* WRITE SAME, NDOB bit */
@@ -245,7 +244,7 @@ struct sdebug_dev_info {
struct sdebug_host_info *sdbg_host;
unsigned long uas_bm[1];
atomic_t num_in_q;
-   char stopped;   /* TODO: should be atomic */
+   atomic_t stopped;
bool used;
 };
 
@@ -262,23 +261,36 @@ struct sdebug_host_info {
 struct sdebug_defer {
struct hrtimer hrt;
struct execute_work ew;
-   int qa_indx;
+   int sqa_idx;/* index of sdebug_queue array */
+   int qc_idx; /* index of sdebug_queued_cmd array within sqa_idx */
+   int issuing_cpu;
 };
 
 struct sdebug_queued_cmd {
-   /* in_use flagged by a bit in queued_in_use_bm[] */
+   /* corresponding bit set in in_use_bm[] in owning struct sdebug_queue
+* instance indicates this slot is in use.
+*/
struct sdebug_defer *sd_dp;
struct scsi_cmnd *a_cmnd;
+   unsigned int inj_recovered:1;
+   unsigned int inj_transport:1;
+   unsigned int inj_dif:1;
+   unsigned int inj_dix:1;
+   unsigned int inj_short:1;
 };
 
-struct sdebug_scmd_extra_t {
-   bool inj_recovered;
-   bool inj_transport;
-   bool inj_dif;
-   bool inj_dix;
-   bool inj_short;
+struct sdebug_queue {
+   struct sdebug_queued_cmd qc_arr[SDEBUG_CANQUEUE];
+   unsigned long in_use_bm[SDEBUG_CANQUEUE_WORDS];
+   spinlock_t qc_lock;
+   atomic_t blocked;   /* to temporarily stop more being queued */
 };
 
+static atomic_t sdebug_cmnd_count;   /* number of incoming commands */
+static atomic_t sdebug_completions;  /* count of deferred completions */
+static atomic_t sdebug_miss_cpus;/* submission + completion cpus differ */
+static atomic_t sdebug_a_tsf;   /* 'almost task set full' counter */
+
 struct opcode_info_t {
u8 num_attached;/* 0 if this is it (i.e. a leaf); use 0xff */
/* for terminating element */
@@ -326,6 +338,7 @@ enum sdeb_opcode_index {
SDEB_I_LAST_ELEMENT = 30,   /* keep this last */
 };
 
+
 static const unsigned char opcode_ind_arr[256] = {
 /* 0x0; 0x0->0x1f: 6 byte cdbs */
SDEB_I_TEST_UNIT_READY, SDEB_I_REZERO_UNIT, 0, SDEB_I_REQUEST_SENSE,
@@ -563,7 +576,7 @@ static int sdebug_fake_rw = DEF_FAKE_RW;
 static unsigned int sdebug_guard = DEF_GUARD;
 static int sdebug_lowest_aligned = DEF_LOWEST_ALIGNED;
 static int sdebug_max_luns = DEF_MAX_LUNS;
-static int sdebug_max_queue = SCSI_DEBUG_CANQUEUE;
+static int sdebug_max_queue = SDEBUG_CANQUEUE; /* per submit queue */
 static atomic_t retired_max_queue; /* if > 0 then was prior max_queue */
 static int sdebug_ndelay = DEF_NDELAY; /* if > 0 then unit is nanoseconds */
 static int 

[PATCH v3 4/6] scsi_debug: vpd and mode page work

2016-05-05 Thread Douglas Gilbert
Cleanup some mode and vpd pages. Stop reporting SBC (disk) pages
when peripheral type is something else (e.g. tape). Update
version descriptors. Expand LBPRZ flag handling.

Reviewed-by: Hannes Reinecke 
Reviewed-by: Bart Van Assche 
Signed-off-by: Douglas Gilbert 
---
 drivers/scsi/scsi_debug.c | 187 ++
 1 file changed, 108 insertions(+), 79 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 2ee55d5..afbbfaa 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -125,7 +125,7 @@ static const char *sdebug_version_date = "20160430";
 #define DEF_PHYSBLK_EXP 0
 #define DEF_PTYPE   TYPE_DISK
 #define DEF_REMOVABLE false
-#define DEF_SCSI_LEVEL   6/* INQUIRY, byte2 [6->SPC-4] */
+#define DEF_SCSI_LEVEL   7/* INQUIRY, byte2 [6->SPC-4; 7->SPC-5] */
 #define DEF_SECTOR_SIZE 512
 #define DEF_UNMAP_ALIGNMENT 0
 #define DEF_UNMAP_GRANULARITY 1
@@ -661,7 +661,11 @@ static const int device_qfull_result =
(DID_OK << 16) | (COMMAND_COMPLETE << 8) | SAM_STAT_TASK_SET_FULL;
 
 
-static inline unsigned int scsi_debug_lbp(void)
+/* Only do the extra work involved in logical block provisioning if one or
+ * more of the lbpu, lbpws or lbpws10 parameters are given and we are doing
+ * real reads and writes (i.e. not skipping them for speed).
+ */
+static inline bool scsi_debug_lbp(void)
 {
return 0 == sdebug_fake_rw &&
(sdebug_lbpu || sdebug_lbpws || sdebug_lbpws10);
@@ -922,10 +926,10 @@ static const u64 naa5_comp_b = 0x5330ULL;
 static const u64 naa5_comp_c = 0x5110ULL;
 
 /* Device identification VPD page. Returns number of bytes placed in arr */
-static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
-  int target_dev_id, int dev_id_num,
-  const char * dev_id_str,
-  int dev_id_str_len)
+static int inquiry_vpd_83(unsigned char *arr, int port_group_id,
+ int target_dev_id, int dev_id_num,
+ const char *dev_id_str,
+ int dev_id_str_len)
 {
int num, port_a;
char b[32];
@@ -1004,14 +1008,14 @@ static unsigned char vpd84_data[] = {
 };
 
 /*  Software interface identification VPD page */
-static int inquiry_evpd_84(unsigned char * arr)
+static int inquiry_vpd_84(unsigned char *arr)
 {
memcpy(arr, vpd84_data, sizeof(vpd84_data));
return sizeof(vpd84_data);
 }
 
 /* Management network addresses VPD page */
-static int inquiry_evpd_85(unsigned char * arr)
+static int inquiry_vpd_85(unsigned char *arr)
 {
int num = 0;
const char * na1 = "https://www.kernel.org/config";;
@@ -1046,7 +1050,7 @@ static int inquiry_evpd_85(unsigned char * arr)
 }
 
 /* SCSI ports VPD page */
-static int inquiry_evpd_88(unsigned char * arr, int target_dev_id)
+static int inquiry_vpd_88(unsigned char *arr, int target_dev_id)
 {
int num = 0;
int port_a, port_b;
@@ -1133,7 +1137,7 @@ static unsigned char vpd89_data[] = {
 };
 
 /* ATA Information VPD page */
-static int inquiry_evpd_89(unsigned char * arr)
+static int inquiry_vpd_89(unsigned char *arr)
 {
memcpy(arr, vpd89_data, sizeof(vpd89_data));
return sizeof(vpd89_data);
@@ -1148,7 +1152,7 @@ static unsigned char vpdb0_data[] = {
 };
 
 /* Block limits VPD page (SBC-3) */
-static int inquiry_evpd_b0(unsigned char * arr)
+static int inquiry_vpd_b0(unsigned char *arr)
 {
unsigned int gran;
 
@@ -1191,7 +1195,7 @@ static int inquiry_evpd_b0(unsigned char * arr)
 }
 
 /* Block device characteristics VPD page (SBC-3) */
-static int inquiry_evpd_b1(unsigned char *arr)
+static int inquiry_vpd_b1(unsigned char *arr)
 {
memset(arr, 0, 0x3c);
arr[0] = 0;
@@ -1202,24 +1206,22 @@ static int inquiry_evpd_b1(unsigned char *arr)
return 0x3c;
 }
 
-/* Logical block provisioning VPD page (SBC-3) */
-static int inquiry_evpd_b2(unsigned char *arr)
+/* Logical block provisioning VPD page (SBC-4) */
+static int inquiry_vpd_b2(unsigned char *arr)
 {
memset(arr, 0, 0x4);
arr[0] = 0; /* threshold exponent */
-
if (sdebug_lbpu)
arr[1] = 1 << 7;
-
if (sdebug_lbpws)
arr[1] |= 1 << 6;
-
if (sdebug_lbpws10)
arr[1] |= 1 << 5;
-
-   if (sdebug_lbprz)
-   arr[1] |= 1 << 2;
-
+   if (sdebug_lbprz && scsi_debug_lbp())
+   arr[1] |= (sdebug_lbprz & 0x7) << 2;  /* sbc4r07 and later */
+   /* anc_sup=0; dp=0 (no provisioning group descriptor) */
+   /* minimum_percentage=0; provisioning_type=0 (unknown) */
+   /* threshold_percentage=0 */
return 0x4;
 }
 
@@ -1232,12 +1234,13 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct 
sdebug_dev_info *devip)
unsigned char * arr;
unsigned char *cmd = scp->cmnd;
int alloc_len, n, ret;
-  

[PATCH v3 2/6] scsi_debug: rework resp_report_luns

2016-05-05 Thread Douglas Gilbert
Based on "[PATH V2] scsi_debug: rework resp_report_luns" patch
sent by Tomas Winkler on Thursday, 26 Feb 2015. His notes:
  1. Remove duplicated boundary checks which simplify the fill-in
 loop
  2. Use more of scsi generic API
Replace fixed length response array a with heap allocation
allowing up to 256 normal LUNs per target.

Reviewed-by: Hannes Reinecke 
Reviewed-by: Bart Van Assche 
Signed-off-by: Douglas Gilbert 
---
 drivers/scsi/scsi_debug.c | 135 +-
 1 file changed, 87 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index fc0246c..e97ddf0 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3208,63 +3208,94 @@ static int resp_get_lba_status(struct scsi_cmnd *scp,
return fill_from_dev_buffer(scp, arr, SDEBUG_GET_LBA_STATUS_LEN);
 }
 
-#define SDEBUG_RLUN_ARR_SZ 256
-
-static int resp_report_luns(struct scsi_cmnd * scp,
-   struct sdebug_dev_info * devip)
+/* Even though each pseudo target has a REPORT LUNS "well known logical unit"
+ * (W-LUN), the normal Linux scanning logic does not associate it with a
+ * device (e.g. /dev/sg7). The following magic will make that association:
+ *   "cd /sys/class/scsi_host/host ; echo '- - 49409' > scan"
+ * where  is a host number. If there are multiple targets in a host then
+ * the above will associate a W-LUN to each target. To only get a W-LUN
+ * for target 2, then use "echo '- 2 49409' > scan" .
+ */
+static int resp_report_luns(struct scsi_cmnd *scp,
+   struct sdebug_dev_info *devip)
 {
+   unsigned char *cmd = scp->cmnd;
unsigned int alloc_len;
-   int lun_cnt, i, upper, num, n, want_wlun, shortish;
+   unsigned char select_report;
u64 lun;
-   unsigned char *cmd = scp->cmnd;
-   int select_report = (int)cmd[2];
-   struct scsi_lun *one_lun;
-   unsigned char arr[SDEBUG_RLUN_ARR_SZ];
-   unsigned char * max_addr;
+   struct scsi_lun *lun_p;
+   u8 *arr;
+   unsigned int lun_cnt;   /* normal LUN count (max: 256) */
+   unsigned int wlun_cnt;  /* report luns W-LUN count */
+   unsigned int tlun_cnt;  /* total LUN count */
+   unsigned int rlen;  /* response length (in bytes) */
+   int i, res;
 
clear_luns_changed_on_target(devip);
-   alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
-   shortish = (alloc_len < 4);
-   if (shortish || (select_report > 2)) {
-   mk_sense_invalid_fld(scp, SDEB_IN_CDB, shortish ? 6 : 2, -1);
+
+   select_report = cmd[2];
+   alloc_len = get_unaligned_be32(cmd + 6);
+
+   if (alloc_len < 4) {
+   pr_err("alloc len too small %d\n", alloc_len);
+   mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1);
return check_condition_result;
}
-   /* can produce response with up to 16k luns (lun 0 to lun 16383) */
-   memset(arr, 0, SDEBUG_RLUN_ARR_SZ);
-   lun_cnt = sdebug_max_luns;
-   if (1 == select_report)
+
+   switch (select_report) {
+   case 0: /* all LUNs apart from W-LUNs */
+   lun_cnt = sdebug_max_luns;
+   wlun_cnt = 0;
+   break;
+   case 1: /* only W-LUNs */
lun_cnt = 0;
-   else if (sdebug_no_lun_0 && (lun_cnt > 0))
+   wlun_cnt = 1;
+   break;
+   case 2: /* all LUNs */
+   lun_cnt = sdebug_max_luns;
+   wlun_cnt = 1;
+   break;
+   case 0x10:  /* only administrative LUs */
+   case 0x11:  /* see SPC-5 */
+   case 0x12:  /* only subsiduary LUs owned by referenced LU */
+   default:
+   pr_debug("select report invalid %d\n", select_report);
+   mk_sense_invalid_fld(scp, SDEB_IN_CDB, 2, -1);
+   return check_condition_result;
+   }
+
+   if (sdebug_no_lun_0 && (lun_cnt > 0))
--lun_cnt;
-   want_wlun = (select_report > 0) ? 1 : 0;
-   num = lun_cnt + want_wlun;
-   arr[2] = ((sizeof(struct scsi_lun) * num) >> 8) & 0xff;
-   arr[3] = (sizeof(struct scsi_lun) * num) & 0xff;
-   n = min((int)((SDEBUG_RLUN_ARR_SZ - 8) /
-   sizeof(struct scsi_lun)), num);
-   if (n < num) {
-   want_wlun = 0;
-   lun_cnt = n;
-   }
-   one_lun = (struct scsi_lun *) &arr[8];
-   max_addr = arr + SDEBUG_RLUN_ARR_SZ;
-   for (i = 0, lun = (sdebug_no_lun_0 ? 1 : 0);
- ((i < lun_cnt) && ((unsigned char *)(one_lun + i) < max_addr));
-i++, lun++) {
-   upper = (lun >> 8) & 0x3f;
-   if (upper)
-   one_lun[i].scsi_lun[0] =
-   (upper | (SAM2_LUN_ADDRESS_METHOD << 6));
-   one_lun[i].scsi_lun[1] = lun & 0xff;
-   }
-   if (want_wlun) {
-   

[PATCH v3 6/6] scsi_debug: use locally assigned naa

2016-05-05 Thread Douglas Gilbert
For reported SAS addresses replace fake IEEE registered NAAs (5)
with locally assigned NAAs (3).

Reviewed-by: Hannes Reinecke 
Reviewed-by: Bart Van Assche 
Signed-off-by: Douglas Gilbert 
---
 drivers/scsi/scsi_debug.c | 35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index efb4549..0f9ba41 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -925,9 +925,10 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *scp, 
unsigned char *arr,
 static const char * inq_vendor_id = "Linux   ";
 static const char * inq_product_id = "scsi_debug  ";
 static const char *inq_product_rev = "0186";   /* version less '.' */
-static const u64 naa5_comp_a = 0x5220ULL;
-static const u64 naa5_comp_b = 0x5330ULL;
-static const u64 naa5_comp_c = 0x5110ULL;
+/* Use some locally assigned NAAs for SAS addresses. */
+static const u64 naa3_comp_a = 0x3220ULL;
+static const u64 naa3_comp_b = 0x3330ULL;
+static const u64 naa3_comp_c = 0x3110ULL;
 
 /* Device identification VPD page. Returns number of bytes placed in arr */
 static int inquiry_vpd_83(unsigned char *arr, int port_group_id,
@@ -961,12 +962,12 @@ static int inquiry_vpd_83(unsigned char *arr, int 
port_group_id,
memcpy(arr + num, lu_name, 16);
num += 16;
} else {
-   /* NAA-5, Logical unit identifier (binary) */
+   /* NAA-3, Logical unit identifier (binary) */
arr[num++] = 0x1;  /* binary (not necessarily sas) */
arr[num++] = 0x3;  /* PIV=0, lu, naa */
arr[num++] = 0x0;
arr[num++] = 0x8;
-   put_unaligned_be64(naa5_comp_b + dev_id_num, arr + num);
+   put_unaligned_be64(naa3_comp_b + dev_id_num, arr + num);
num += 8;
}
/* Target relative port number */
@@ -979,14 +980,14 @@ static int inquiry_vpd_83(unsigned char *arr, int 
port_group_id,
arr[num++] = 0x0;
arr[num++] = 0x1;   /* relative port A */
}
-   /* NAA-5, Target port identifier */
+   /* NAA-3, Target port identifier */
arr[num++] = 0x61;  /* proto=sas, binary */
arr[num++] = 0x93;  /* piv=1, target port, naa */
arr[num++] = 0x0;
arr[num++] = 0x8;
-   put_unaligned_be64(naa5_comp_a + port_a, arr + num);
+   put_unaligned_be64(naa3_comp_a + port_a, arr + num);
num += 8;
-   /* NAA-5, Target port group identifier */
+   /* NAA-3, Target port group identifier */
arr[num++] = 0x61;  /* proto=sas, binary */
arr[num++] = 0x95;  /* piv=1, target port group id */
arr[num++] = 0x0;
@@ -995,19 +996,19 @@ static int inquiry_vpd_83(unsigned char *arr, int 
port_group_id,
arr[num++] = 0;
put_unaligned_be16(port_group_id, arr + num);
num += 2;
-   /* NAA-5, Target device identifier */
+   /* NAA-3, Target device identifier */
arr[num++] = 0x61;  /* proto=sas, binary */
arr[num++] = 0xa3;  /* piv=1, target device, naa */
arr[num++] = 0x0;
arr[num++] = 0x8;
-   put_unaligned_be64(naa5_comp_a + target_dev_id, arr + num);
+   put_unaligned_be64(naa3_comp_a + target_dev_id, arr + num);
num += 8;
/* SCSI name string: Target device identifier */
arr[num++] = 0x63;  /* proto=sas, UTF-8 */
arr[num++] = 0xa8;  /* piv=1, target device, SCSI name string */
arr[num++] = 0x0;
arr[num++] = 24;
-   memcpy(arr + num, "naa.5220", 12);
+   memcpy(arr + num, "naa.3220", 12);
num += 12;
snprintf(b, sizeof(b), "%08X", target_dev_id);
memcpy(arr + num, b, 8);
@@ -1086,7 +1087,7 @@ static int inquiry_vpd_88(unsigned char *arr, int 
target_dev_id)
arr[num++] = 0x93;  /* PIV=1, target port, NAA */
arr[num++] = 0x0;   /* reserved */
arr[num++] = 0x8;   /* length */
-   put_unaligned_be64(naa5_comp_a + port_a, arr + num);
+   put_unaligned_be64(naa3_comp_a + port_a, arr + num);
num += 8;
arr[num++] = 0x0;   /* reserved */
arr[num++] = 0x0;   /* reserved */
@@ -1101,7 +1102,7 @@ static int inquiry_vpd_88(unsigned char *arr, int 
target_dev_id)
arr[num++] = 0x93;  /* PIV=1, target port, NAA */
arr[num++] = 0x0;   /* reserved */
arr[num++] = 0x8;   /* length */
-   put_unaligned_be64(naa5_comp_a + port_b, arr + num);
+   put_unaligned_be64(naa3_comp_a + port_b, arr + num);
num += 8;
 
return num;
@@ -1931,10 +1932,10 @@ static int resp_sas_pcd_m_spg(unsigned char * p, int 
pcontrol, int target,
};
  

[PATCH v3 5/6] scsi_debug: uuid for lu name

2016-05-05 Thread Douglas Gilbert
Permit changing of a LU name from a (fake) IEEE registered NAA (5)
to a locally assigned UUID. Using a UUID (RFC 4122) for a SCSI
designation descriptor (e.g. a LU name) was added in spc5r08.pdf
(a draft INCITS standard) on 25 January 2016. Add parameter
uuid_ctl to use a separate UUID for each LU (storage device) name.
Additional option for all LU names to have the same UUID (since
their storage is shared). Previous action of using NAA identifier
for LU name remains the default.

Reviewed-by: Hannes Reinecke 
Reviewed-by: Bart Van Assche 
Signed-off-by: Douglas Gilbert 
---
 drivers/scsi/scsi_debug.c | 61 +++
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index afbbfaa..efb4549 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -137,6 +138,7 @@ static const char *sdebug_version_date = "20160430";
 #define DEF_STRICT 0
 #define DEF_STATISTICS false
 #define DEF_SUBMIT_QUEUES 1
+#define DEF_UUID_CTL 0
 #define JDELAY_OVERRIDDEN -
 
 #define SDEBUG_LUN_0_VAL 0
@@ -241,6 +243,7 @@ struct sdebug_dev_info {
unsigned int channel;
unsigned int target;
u64 lun;
+   uuid_be lu_name;
struct sdebug_host_info *sdbg_host;
unsigned long uas_bm[1];
atomic_t num_in_q;
@@ -600,6 +603,7 @@ static unsigned int sdebug_unmap_granularity = 
DEF_UNMAP_GRANULARITY;
 static unsigned int sdebug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS;
 static unsigned int sdebug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
 static unsigned int sdebug_write_same_length = DEF_WRITESAME_LENGTH;
+static int sdebug_uuid_ctl = DEF_UUID_CTL;
 static bool sdebug_removable = DEF_REMOVABLE;
 static bool sdebug_clustering;
 static bool sdebug_host_lock = DEF_HOST_LOCK;
@@ -928,8 +932,8 @@ static const u64 naa5_comp_c = 0x5110ULL;
 /* Device identification VPD page. Returns number of bytes placed in arr */
 static int inquiry_vpd_83(unsigned char *arr, int port_group_id,
  int target_dev_id, int dev_id_num,
- const char *dev_id_str,
- int dev_id_str_len)
+ const char *dev_id_str, int dev_id_str_len,
+ const uuid_be *lu_name)
 {
int num, port_a;
char b[32];
@@ -946,13 +950,25 @@ static int inquiry_vpd_83(unsigned char *arr, int 
port_group_id,
arr[3] = num;
num += 4;
if (dev_id_num >= 0) {
-   /* NAA-5, Logical unit identifier (binary) */
-   arr[num++] = 0x1;   /* binary (not necessarily sas) */
-   arr[num++] = 0x3;   /* PIV=0, lu, naa */
-   arr[num++] = 0x0;
-   arr[num++] = 0x8;
-   put_unaligned_be64(naa5_comp_b + dev_id_num, arr + num);
-   num += 8;
+   if (sdebug_uuid_ctl) {
+   /* Locally assigned UUID */
+   arr[num++] = 0x1;  /* binary (not necessarily sas) */
+   arr[num++] = 0xa;  /* PIV=0, lu, naa */
+   arr[num++] = 0x0;
+   arr[num++] = 0x12;
+   arr[num++] = 0x10; /* uuid type=1, locally assigned */
+   arr[num++] = 0x0;
+   memcpy(arr + num, lu_name, 16);
+   num += 16;
+   } else {
+   /* NAA-5, Logical unit identifier (binary) */
+   arr[num++] = 0x1;  /* binary (not necessarily sas) */
+   arr[num++] = 0x3;  /* PIV=0, lu, naa */
+   arr[num++] = 0x0;
+   arr[num++] = 0x8;
+   put_unaligned_be64(naa5_comp_b + dev_id_num, arr + num);
+   num += 8;
+   }
/* Target relative port number */
arr[num++] = 0x61;  /* proto=sas, binary */
arr[num++] = 0x94;  /* PIV=1, target port, rel port */
@@ -1293,7 +1309,8 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct 
sdebug_dev_info *devip)
arr[1] = cmd[2];/*sanity */
arr[3] = inquiry_vpd_83(&arr[4], port_group_id,
target_dev_id, lu_id_num,
-   lu_id_str, len);
+   lu_id_str, len,
+   &devip->lu_name);
} else if (0x84 == cmd[2]) { /* Software interface ident. */
arr[1] = cmd[2];/*sanity */
arr[3] = inquiry_vpd_84(&arr[4]);
@@ -3503,6 +3520,9 @@ static void sdebug_q_cmd_wq_complete(struct work_struct 
*work)
sdebug_q_cmd_complete(sd_dp);
 }
 
+static bool got_shared_uu