ALUA device handler update, part 1
cover ALUA device handler update, part 1
Hi all,
here's the first part of my ALUA device handler update. It's mainly bugfixes and minor improvements; the two important things are the addition of VPD parsing functions scsi_vpd_lun_id() and scsi_vpd_tpg_id().
This series has been split off from the original 'Asynchronous ALUA' patchset, as these bits are pretty uncontroversial and have a good chance of being merged reasonably soon.
The second part of the ALUA device handler update will be posted (and, doubtlessly, discussed) once this part is in.
Patch is relative to 4.4/scsi-queue by mkp, and based upon the 'scsi: rescan VPD attributes' patch I send earlier.
As usual, comments and reviews are welcome.
Hannes Reinecke (18):
scsi_dh: move 'dh_state' sysfs attribute to generic code
scsi: ignore errors from scsi_dh_add_device()
scsi_dh_alua: Disable ALUA handling for non-disk devices
scsi_dh_alua: Use vpd_pg83 information
scsi_dh_alua: improved logging
scsi_dh_alua: sanitze sense code handling
scsi_dh_alua: use standard logging functions
scsi_dh_alua: return standard SCSI return codes in submit_rtpg
scsi_dh_alua: fixup description of stpg_endio()
scsi: remove scsi_show_sense_hdr()
scsi_dh_alua: use flag for RTPG extended header
scsi_dh_alua: use unaligned access macros
scsi_dh_alua: rework alua_check_tpgs() to return the tpgs mode
scsi_dh_alua: simplify sense code handling
scsi: Add scsi_vpd_lun_id()
scsi: export 'device_id' to sysfs
scsi: Add scsi_vpd_tpg_id()
scsi_dh_alua: use scsi_vpd_tpg_id()
drivers/scsi/device_handler/scsi_dh_alua.c | 294 ++++++++++------------------- drivers/scsi/scsi_dh.c | 68 +------ drivers/scsi/scsi_lib.c | 188 ++++++++++++++++++ drivers/scsi/scsi_sysfs.c | 82 +++++++- include/scsi/scsi_dbg.h | 2 - include/scsi/scsi_device.h | 2 + 6 files changed, 373 insertions(+), 263 deletions(-)
Signature · 1 line
1.8.5.6
PATCH 1/18 scsi_dh: move 'dh_state' sysfs attribute to generic code
As scsi_dh.c is now always compiled in we should be moving the 'dh_state' attribute to the generic code.
--- drivers/scsi/scsi_dh.c | 68 +---------------------------------------------- drivers/scsi/scsi_sysfs.c | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 67 deletions(-)
drivers/scsi/scsi_dh.c +1 -67
@@ -153,76 +153,11 @@ static void scsi_dh_handler_detach(struct scsi_device *sdev)module_put (sdev->handler->module); } -/* -* Functions for sysfs attribute 'dh_state' -*/ -static ssize_t -store_dh_state (struct device *dev,struct device_attribute *attr, -const char *buf,size_t count) -{ -struct scsi_device *sdev =to_scsi_device (dev); -struct scsi_device_handler *scsi_dh; -int err = -EINVAL ; - -if (sdev->sdev_state ==SDEV_CANCEL || - sdev->sdev_state ==SDEV_DEL ) -return -ENODEV ; - -if (!sdev->handler) { -/* -* Attach to a device handler -*/ - scsi_dh =scsi_dh_lookup (buf); -if (!scsi_dh) -return err; - err =scsi_dh_handler_attach (sdev, scsi_dh); - }else { -if (!strncmp (buf,"detach" ,6 )) { -/* -* Detach from a device handler -*/ -sdev_printk (KERN_WARNING , sdev, -"can't detach handler %s.\n" , - sdev->handler->name); - err = -EINVAL ; - }else if (!strncmp (buf,"activate" ,8 )) { -/* -* Activate a device handler -*/ -if (sdev->handler->activate) - err = sdev->handler->activate (sdev,NULL ,NULL ); -else - err =0 ; - } - } - -return err<0 ?err:count; -} - -static ssize_t -show_dh_state (struct device *dev,struct device_attribute *attr,char *buf) -{ -struct scsi_device *sdev =to_scsi_device (dev); - -if (!sdev->handler) -return snprintf (buf,20 ,"detached\n" ); - -return snprintf (buf,20 ,"%s\n" , sdev->handler->name); -} - -static struct device_attribute scsi_dh_state_attr = -__ATTR (dh_state,S_IRUGO |S_IWUSR , show_dh_state, - store_dh_state); -int scsi_dh_add_device (struct scsi_device *sdev) {struct scsi_device_handler *devinfo =NULL ;const char *drv; -int err; - - err =device_create_file (&sdev->sdev_gendev, &scsi_dh_state_attr); -if (err) -return err; +int err =0 ; drv =scsi_dh_find_driver (sdev);if (drv)
@@ -236,7 +171,6 @@ void scsi_dh_remove_device(struct scsi_device *sdev) {if (sdev->handler)scsi_dh_handler_detach (sdev); -device_remove_file (&sdev->sdev_gendev, &scsi_dh_state_attr); }/*
drivers/scsi/scsi_sysfs.c +58 -0
76 lines not on this page · raw message
Signature · 1 line
1.8.5.6
Re: [PATCH 01/18] scsi_dh: move 'dh_state' sysfs attribute to generic code
Quoted 185 lines · Hannes Reinecke
As
scsi_dh.cis now always compiled in we should be moving the 'dh_state' attribute to the generic code.Reviewed-by Christoph Hellwig <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/scsi_dh.c | 68 +----------------------------------
------------
drivers/scsi/scsi_sysfs.c | 58
++++++++++++++++++++++++++++++++++++++++2 files changed, 59 insertions(+), 67 deletions(-)drivers/scsi/scsi_dh.c +0
-0@@ -153,76 +153,11 @@ static void scsi_dh_handler_detach(struct scsi_device *sdev) module_put(sdev->handler->module); }drivers/scsi/scsi_dh.c +0
-38-/* -* Functions for sysfs attribute 'dh_state' -*/ -static ssize_t -store_dh_state (struct device *dev,struct device_attribute *attr, - const char *buf, size_t count) -{ -struct scsi_device *sdev =to_scsi_device (dev); -struct scsi_device_handler *scsi_dh; -int err = -EINVAL ; - -if (sdev->sdev_state ==SDEV_CANCEL || - sdev->sdev_state == SDEV_DEL) -return -ENODEV ; - -if (!sdev->handler) { -/* -* Attach to a device handler -*/ - scsi_dh =scsi_dh_lookup (buf); -if (!scsi_dh) -return err; - err =scsi_dh_handler_attach (sdev, scsi_dh); - }else { -if (!strncmp (buf,"detach" ,6 )) { -/* -* Detach from a device handler -*/ -sdev_printk (KERN_WARNING , sdev, - "can't detach handler %s.\n", - sdev->handler->name); - err = -EINVAL ; - }else if (!strncmp (buf,"activate" ,8 )) { -/* -* Activate a device handler -*/ -if (sdev->handler->activate) - err = sdev->handler->activate(sdev,NULL, NULL);
drivers/scsi/scsi_dh.c +0
-10-else - err =0 ; - } - } - -return err<0 ?err:count; -} - -static ssize_t -show_dh_state(struct device *dev, struct device_attribute *attr,char *buf)
drivers/scsi/scsi_dh.c +0
-13-{ -struct scsi_device *sdev =to_scsi_device (dev); - -if (!sdev->handler) -return snprintf (buf,20 ,"detached\n" ); - -return snprintf (buf,20 ,"%s\n" , sdev->handler->name); -} - -static struct device_attribute scsi_dh_state_attr = -__ATTR (dh_state,S_IRUGO |S_IWUSR , show_dh_state, - store_dh_state); -int
scsi_dh_add_device(struct scsi_device *sdev){
structscsi_device_handler*devinfo = NULL; const char *drv;drivers/scsi/scsi_dh.c +0
-3-int err; - - err = device_create_file(&sdev->sdev_gendev,
&scsi_dh_state_attr);drivers/scsi/scsi_dh.c +1
-2-if (err) -return err; +int err =0 ;
drv =scsi_dh_find_driver(sdev);
if (drv)drivers/scsi/scsi_dh.c +0
-1@@ -236,7 +171,6 @@ void scsi_dh_remove_device(struct scsi_device *sdev) { if (sdev->handler) scsi_dh_handler_detach(sdev); -device_remove_file (&sdev->sdev_gendev, &scsi_dh_state_attr); }
/*drivers/scsi/scsi_sysfs.c +1
-0@@ -17,6 +17,7 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> +#include <scsi/scsi_dh.h> #include <scsi/scsi_transport.h> #include <scsi/scsi_driver.h>drivers/scsi/scsi_sysfs.c +0
-0@@ -902,6 +903,60 @@ sdev_show_function(queue_depth, "%d\n"); static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth, sdev_store_queue_depth);drivers/scsi/scsi_sysfs.c +3
-0+#ifdef CONFIG_SCSI_DH +static ssize_t +sdev_show_dh_state(struct device *dev, struct device_attribute*attr,
drivers/scsi/scsi_sysfs.c +12
-0+ char *buf) +{ +struct scsi_device *sdev =to_scsi_device (dev); + +if (!sdev->handler) +return snprintf (buf,20 ,"detached\n" ); + +return snprintf (buf,20 ,"%s\n" , sdev->handler->name); +} + +static ssize_t +sdev_store_dh_state(struct device *dev, struct device_attribute*attr,
drivers/scsi/scsi_sysfs.c +20
-0+ const char *buf, size_t count) +{ +struct scsi_device *sdev =to_scsi_device (dev); +int err = -EINVAL ; + +if (sdev->sdev_state ==SDEV_CANCEL || + sdev->sdev_state == SDEV_DEL) +return -ENODEV ; + +if (!sdev->handler) { +/* +* Attach to a device handler +*/ + err =scsi_dh_attach (sdev->request_queue, buf); + }else if (!strncmp (buf,"activate" ,8 )) { +/* +* Activate a device handler +*/ +if (sdev->handler->activate) + err = sdev->handler->activate(sdev, NULL,NULL);
drivers/scsi/scsi_sysfs.c +19
-0+ else + err = 0; + }else if (!strncmp (buf,"detach" ,6 )) { +/* +* Detach from a device handler +*/ +sdev_printk (KERN_WARNING , sdev, + "can't detach handler %s.\n", + sdev->handler->name); + err = -EINVAL ; + } + +return err <0 ? err : count; +} + +static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state, + sdev_store_dh_state); +#endif +static
ssize_tsdev_show_queue_ramp_up_period(struct device *dev, structdevice_attribute*attr,
drivers/scsi/scsi_sysfs.c static struct attribute *scsi_sdev_attrs[] = { · line 1034
Quoted 9 lines
drivers/scsi/scsi_sysfs.c +3
-0@@ -971,6 +1026,9 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_modalias.attr, &dev_attr_queue_depth.attr, &dev_attr_queue_type.attr, +#ifdef CONFIG_SCSI_DH + &dev_attr_dh_state.attr, +#endif &dev_attr_queue_ramp_up_period.attr, REF_EVT(media_change), REF_EVT(inquiry_change_reported),
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/18] scsi_dh: move 'dh_state' sysfs attribute to generic code
In reply to Hannes ReineckeQuoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Hannes" == Hannes Reinecke <[email protected]> writes:
Hannes> As scsi_dh.c is now always compiled in we should be moving the Hannes> 'dh_state' attribute to the generic code.
This patch conflicts with 23695e41a1ca ("scsi_dh: fix use-after-free when removing scsi device").
Looked simple enough and I started to fix it up but then decided to let you do since you'll have to check it anyway.
Please rebase on top of latest 4.5/scsi-queue (which has your VPD rescan patch in place).
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
PATCH 2/18 scsi: ignore errors from scsi_dh_add_device()
In reply to Hannes Reineckedevice handler initialisation might fail due to a number of reasons. But as device_handlers are optional this shouldn't cause us to disable the device entirely.
So just ignore errors from scsi_dh_add_device().
--- drivers/scsi/scsi_sysfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/scsi/scsi_sysfs.c +4 -3
@@ -1118,11 +1118,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) } error =scsi_dh_add_device (sdev); -if (error) { +if (error) +/* +* device_handler is optional, so any error can be ignored +*/ sdev_printk (KERN_INFO , sdev,"failed to add device handler: %d\n" , error); -return error; - }device_enable_async_suspend (&sdev->sdev_dev); error =device_add (&sdev->sdev_dev);
Signature · 1 line
1.8.5.6
Re: [PATCH 02/18] scsi: ignore errors from scsi_dh_add_device()
Quoted 30 lines · Hannes Reinecke
device handler initialisation might fail due to a number of reasons. But as
device_handlersare optional this shouldn't cause us to disable the device entirely.
So just ignore errors fromscsi_dh_add_device().Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/scsi_sysfs.c | 7 ++++---1 file changed, 4 insertions(+), 3 deletions(-)drivers/scsi/scsi_sysfs.c +0
-0@@ -1118,11 +1118,12 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) }
error =scsi_dh_add_device(sdev);drivers/scsi/scsi_sysfs.c +3
-1-if (error) { +if (error) +/* +* device_handler is optional, so any error can be ignored
drivers/scsi/scsi_sysfs.c +1
-0+*/ sdev_printk(KERN_INFO, sdev,
"failed to add device handler:
%d\n", error);drivers/scsi/scsi_sysfs.c +0
-2-return error; - }
Quoted 3 lines
device_enable_async_suspend(&sdev->sdev_dev); error =device_add(&sdev->sdev_dev);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/18 scsi_dh_alua: Disable ALUA handling for non-disk devices
In reply to Hannes ReineckeNon-disk devices might support ALUA, but the firmware implementation is untested and frequently broken. As we're don't actually need it disable ALUA support for non-disk device for now.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/scsi/device_handler/scsi_dh_alua.c +12 -0
@@ -320,6 +320,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) {int err =SCSI_DH_OK ; +/* +* ALUA support for non-disk devices is fraught with +* difficulties, so disable it for now. +*/ +if (sdev->type !=TYPE_DISK ) { + h->tpgs =TPGS_MODE_NONE ; +sdev_printk (KERN_INFO , sdev, +"%s: disable for non-disk devices\n" , +ALUA_DH_NAME ); +return SCSI_DH_DEV_UNSUPP ; + } + h->tpgs =scsi_device_tpgs (sdev);switch (h->tpgs) {case TPGS_MODE_EXPLICIT |TPGS_MODE_IMPLICIT :
Signature · 1 line
1.8.5.6
Re: [PATCH 03/18] scsi_dh_alua: Disable ALUA handling for non-disk devices
Quoted 35 lines · Hannes Reinecke
Non-disk devices might support ALUA, but the firmware implementation is untested and frequently broken. As we're don't actually need it disable ALUA support for non-disk device for now.
Signed-off-by Hannes Reinecke <[email protected]>Reviewed-by Bart Van Assche <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Martin K. Petersen <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 12 ++++++++++++1 file changed, 12 insertions(+)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -320,6 +320,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) { int err = SCSI_DH_OK;drivers/scsi/device_handler/scsi_dh_alua.c +12
-0+/* +* ALUA support for non-disk devices is fraught with +* difficulties, so disable it for now. +*/ +if (sdev->type !=TYPE_DISK ) { + h->tpgs =TPGS_MODE_NONE ; +sdev_printk (KERN_INFO , sdev, + "%s: disable for non-disk devices\n", + ALUA_DH_NAME); +return SCSI_DH_DEV_UNSUPP ; + } +
Quoted 3 lines
h->tpgs=scsi_device_tpgs(sdev); switch (h->tpgs) {
case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/18 scsi_dh_alua: Use vpd_pg83 information
In reply to Hannes ReineckeThe SCSI device now has the VPD page 0x83 information attached, so there is no need to query it again.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 87 +++++++----------------------- 1 file changed, 18 insertions(+), 69 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +18 -69
@@ -131,43 +131,6 @@ static struct request *get_alua_req(struct scsi_device *sdev, }/* -* submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command -* @sdev: sdev the command should be sent to -*/ -static int submit_vpd_inquiry (struct scsi_device *sdev,struct alua_dh_data *h) -{ -struct request *rq; -int err =SCSI_DH_RES_TEMP_UNAVAIL ; - - rq =get_alua_req (sdev, h->buff, h->bufflen,READ ); -if (!rq) - goto done; - -/* Prepare the command. */ - rq->cmd[0 ] =INQUIRY ; - rq->cmd[1 ] =1 ; - rq->cmd[2 ] =0x83 ; - rq->cmd[4 ] = h->bufflen; - rq->cmd_len =COMMAND_SIZE (INQUIRY ); - - rq->sense = h->sense; -memset (rq->sense,0 ,SCSI_SENSE_BUFFERSIZE ); - rq->sense_len = h->senselen =0 ; - - err =blk_execute_rq (rq->q,NULL , rq,1 ); -if (err == -EIO ) { -sdev_printk (KERN_INFO , sdev, -"%s: evpd inquiry failed with %x\n" , -ALUA_DH_NAME , rq->errors); - h->senselen = rq->sense_len; - err =SCSI_DH_IO ; - } -blk_put_request (rq); -done: -return err; -} - -/* * submit_rtpg - Issue a REPORT TARGET GROUP STATES command * @sdev: sdev the command should be sent to */
@@ -359,43 +322,29 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) }/* -* alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83 +* alua_check_vpd - Evaluate INQUIRY vpd page 0x83 * @sdev: device to be checked * * Extract the relative target port and the target port group * descriptor from the list of identificators. */ -static int alua_vpd_inquiry (struct scsi_device *sdev,struct alua_dh_data *h) +static int alua_check_vpd (struct scsi_device *sdev,struct alua_dh_data *h) { -int len; -unsigned err;unsigned char *d; +unsigned char __rcu *vpd_pg83; - retry: - err =submit_vpd_inquiry (sdev, h); - -if (err !=SCSI_DH_OK ) -return err; - -/* Check if vpd page exceeds initial buffer */ - len = (h->buff[2 ] <<8 ) + h->buff[3 ] +4 ; -if (len > h->bufflen) { -/* Resubmit with the correct length */ -if (realloc_buffer (h, len)) { -sdev_printk (KERN_WARNING , sdev, -"%s: kmalloc buffer failed\n" , -ALUA_DH_NAME ); -/* Temporary failure, bypass */ -return SCSI_DH_DEV_TEMP_BUSY ; - } - goto retry; +rcu_read_lock (); +if (!rcu_dereference (sdev->vpd_pg83)){ +rcu_read_unlock (); +return SCSI_DH_DEV_UNSUPP ; }/* -* Now look for the correct descriptor. +* Look for the correct descriptor. */ - d = h->buff +4 ; -while (d < h->buff + len) { + vpd_pg83 =rcu_dereference (sdev->vpd_pg83); + d = vpd_pg83 +4 ; +while (d < vpd_pg83 + sdev->vpd_pg83_len) {switch (d[1 ] &0xf ) {case 0x4 :/* Relative target port */
@@ -410,6 +359,7 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) } d += d[3 ] +4 ; } +rcu_read_unlock ();if (h->group_id ==-1 ) {/*
@@ -422,14 +372,13 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) ALUA_DH_NAME); h->state =TPGS_STATE_OPTIMIZED ; h->tpgs =TPGS_MODE_NONE ; - err =SCSI_DH_DEV_UNSUPP ; - }else { -sdev_printk (KERN_INFO , sdev, -"%s: port group %02x rel port %02x\n" , -ALUA_DH_NAME , h->group_id, h->rel_port); +return SCSI_DH_DEV_UNSUPP ; } +sdev_printk (KERN_INFO , sdev, +"%s: port group %02x rel port %02x\n" , +ALUA_DH_NAME , h->group_id, h->rel_port); -return err; +return 0 ; }static char print_alua_state (int state)
@@ -692,7 +641,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)if (err !=SCSI_DH_OK ) goto out; - err =alua_vpd_inquiry (sdev, h); + err =alua_check_vpd (sdev, h);if (err !=SCSI_DH_OK ) goto out;
Signature · 1 line
1.8.5.6
Re: [PATCH 04/18] scsi_dh_alua: Use vpd_pg83 information
Quoted 157 lines · Hannes Reinecke
The SCSI device now has the VPD page
0x83information attached, so there is no need to query it again.Reviewed-by Martin K. Petersen <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 87 +++++++-------------
----------1 file changed, 18 insertions(+), 69 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -131,43 +131,6 @@ static struct request *get_alua_req(struct scsi_device *sdev, }
/*
- *submit_vpd_inquiry- Issue an INQUIRY VPD page0x83command
- * @sdev: sdev the command should be sent to
- */
-static intsubmit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)drivers/scsi/device_handler/scsi_dh_alua.c +0
-33-{ -struct request *rq; -int err =SCSI_DH_RES_TEMP_UNAVAIL ; - - rq =get_alua_req (sdev, h->buff, h->bufflen,READ ); -if (!rq) - goto done; - -/* Prepare the command. */ - rq->cmd[0 ] =INQUIRY ; - rq->cmd[1 ] =1 ; - rq->cmd[2 ] =0x83 ; - rq->cmd[4 ] = h->bufflen; - rq->cmd_len =COMMAND_SIZE (INQUIRY ); - - rq->sense = h->sense; -memset (rq->sense,0 ,SCSI_SENSE_BUFFERSIZE ); - rq->sense_len = h->senselen =0 ; - - err =blk_execute_rq (rq->q,NULL , rq,1 ); -if (err == -EIO ) { -sdev_printk (KERN_INFO , sdev, - "%s: evpd inquiry failed with %x\n", - ALUA_DH_NAME, rq->errors); - h->senselen = rq->sense_len; - err =SCSI_DH_IO ; - } -blk_put_request (rq); -done: -return err; -} - -/* *
submit_rtpg- Issue a REPORT TARGET GROUP STATES command
* @sdev: sdev the command should be sent to
*/drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -359,43 +322,29 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h) }
/*
- *alua_vpd_inquiry- Evaluate INQUIRY vpd page0x83
+ *alua_check_vpd- Evaluate INQUIRY vpd page0x83
* @sdev: device to be checked
*
* Extract the relative target port and the target port group
* descriptor from the list of identificators.
*/
-static intalua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
+static intalua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h)
{drivers/scsi/device_handler/scsi_dh_alua.c +0
-2-int len; -unsigned err;unsigned char *d;
drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+unsigned char __rcu *vpd_pg83;
- retry:drivers/scsi/device_handler/scsi_dh_alua.c +4
-17- err =submit_vpd_inquiry (sdev, h); - -if (err !=SCSI_DH_OK ) -return err; - -/* Check if vpd page exceeds initial buffer */ - len = (h->buff[2 ] <<8 ) + h->buff[3 ] +4 ; -if (len > h->bufflen) { -/* Resubmit with the correct length */ -if (realloc_buffer (h, len)) { -sdev_printk (KERN_WARNING , sdev, - "%s: kmalloc buffer failed\n", - ALUA_DH_NAME); -/* Temporary failure, bypass */ -return SCSI_DH_DEV_TEMP_BUSY ; - } - goto retry; +rcu_read_lock (); +if (!rcu_dereference (sdev->vpd_pg83)){ +rcu_read_unlock (); +return SCSI_DH_DEV_UNSUPP ;}
/*drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- * Now look for the correct descriptor. + * Look for the correct descriptor.*/
drivers/scsi/device_handler/scsi_dh_alua.c +3
-2- d = h->buff +4 ; -while (d < h->buff + len) { + vpd_pg83 =rcu_dereference (sdev->vpd_pg83); + d = vpd_pg83 +4 ; +while (d < vpd_pg83 + sdev->vpd_pg83_len) {switch (d[1] &
0xf) {
case0x4:
/* Relative target port */drivers/scsi/device_handler/scsi_dh_alua.c +1
-0@@ -410,6 +359,7 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) } d += d[3] + 4; } +rcu_read_unlock ();
if (h->group_id== -1) {
/*drivers/scsi/device_handler/scsi_dh_alua.c +4
-5@@ -422,14 +372,13 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h) ALUA_DH_NAME); h->state = TPGS_STATE_OPTIMIZED; h->tpgs = TPGS_MODE_NONE; - err =SCSI_DH_DEV_UNSUPP ; - }else { -sdev_printk (KERN_INFO , sdev, - "%s: port group %02x rel port %02x\n", - ALUA_DH_NAME, h->group_id, h->rel_port); +return SCSI_DH_DEV_UNSUPP ; } +sdev_printk (KERN_INFO , sdev, + "%s: port group %02x rel port %02x\n", + ALUA_DH_NAME, h->group_id, h->rel_port);drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-return err; +return 0 ;}
static charprint_alua_state(int state)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -692,7 +641,7 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h) if (err != SCSI_DH_OK) goto out;drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- err =alua_vpd_inquiry (sdev, h); + err =alua_check_vpd (sdev, h);
Quoted 3 lines
if (err !=
SCSI_DH_OK)
goto out;
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/18 scsi_dh_alua: improved logging
In reply to Hannes ReineckeIssue different logging messages if ALUA is not supported or the TPGS setting is invalid.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +8 -2
@@ -310,12 +310,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h)sdev_printk (KERN_INFO , sdev,"%s: supports implicit TPGS\n" ,ALUA_DH_NAME );break ; -default : - h->tpgs =TPGS_MODE_NONE ; +case TPGS_MODE_NONE :sdev_printk (KERN_INFO , sdev,"%s: not supported\n" ,ALUA_DH_NAME ); err =SCSI_DH_DEV_UNSUPP ;break ; +default : +sdev_printk (KERN_INFO , sdev, +"%s: unsupported TPGS setting %d\n" , +ALUA_DH_NAME , h->tpgs); + h->tpgs =TPGS_MODE_NONE ; + err =SCSI_DH_DEV_UNSUPP ; +break ; }return err;
Signature · 1 line
1.8.5.6
Re: [PATCH 05/18] scsi_dh_alua: improved logging
Quoted 35 lines · Hannes Reinecke
Issue different logging messages if ALUA is not supported or the TPGS setting is invalid.
Reviewed-by Martin K. Petersen <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 10 ++++++++--1 file changed, 8 insertions(+), 2 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -310,12 +310,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h)sdev_printk(KERN_INFO, sdev, "%s: supports implicit TPGS\n",
ALUA_DH_NAME);
break;drivers/scsi/device_handler/scsi_dh_alua.c +1
-2-default : - h->tpgs =TPGS_MODE_NONE ; +case TPGS_MODE_NONE :
sdev_printk(KERN_INFO, sdev, "%s: not supported\n", ALUA_DH_NAME);
err =SCSI_DH_DEV_UNSUPP;
break;drivers/scsi/device_handler/scsi_dh_alua.c +7
-0+default : +sdev_printk (KERN_INFO , sdev, + "%s: unsupported TPGS setting %d\n", + ALUA_DH_NAME, h->tpgs); + h->tpgs =TPGS_MODE_NONE ; + err =SCSI_DH_DEV_UNSUPP ; +break ;
Quoted 3 lines
}
return err;
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/18 scsi_dh_alua: sanitze sense code handling
In reply to Hannes ReineckeThe only check for a valid sense code is calling scsi_normalize_sense() and check the return value. So drop the pointless checks and rely on scsi_normalize_sense() to figure out if the sense code is valid. With that we can also remove the 'senselen' field.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +7 -11
@@ -73,7 +73,6 @@ struct alua_dh_data {int bufflen;unsigned char transition_tmo;unsigned char sense[SCSI_SENSE_BUFFERSIZE ]; -int senselen;struct scsi_device *sdev;activate_complete callback_fn;void *callback_data;
@@ -158,14 +157,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, rq->sense = h->sense;memset (rq->sense,0 ,SCSI_SENSE_BUFFERSIZE ); - rq->sense_len = h->senselen =0 ; + rq->sense_len =0 ; err =blk_execute_rq (rq->q,NULL , rq,1 );if (err == -EIO ) {sdev_printk (KERN_INFO , sdev,"%s: rtpg failed with %x\n" ,ALUA_DH_NAME , rq->errors); - h->senselen = rq->sense_len; err =SCSI_DH_IO ; }blk_put_request (rq);
@@ -194,9 +192,8 @@ static void stpg_endio(struct request *req, int error) goto done; } -if (req->sense_len >0 ) { - err =scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , - &sense_hdr); +if (scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , + &sense_hdr)) {if (!err) { err =SCSI_DH_IO ; goto done;
@@ -265,7 +262,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) rq->sense = h->sense;memset (rq->sense,0 ,SCSI_SENSE_BUFFERSIZE ); - rq->sense_len = h->senselen =0 ; + rq->sense_len =0 ; rq->end_io_data = h;blk_execute_rq_nowait (rq->q,NULL , rq,1 , stpg_endio);
@@ -514,10 +511,9 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ retry: err =submit_rtpg (sdev, h, rtpg_ext_hdr_req); -if (err ==SCSI_DH_IO && h->senselen >0 ) { - err =scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , - &sense_hdr); -if (!err) +if (err ==SCSI_DH_IO ) { +if (!scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , + &sense_hdr))return SCSI_DH_IO ;/*
Signature · 1 line
1.8.5.6
Re: [PATCH 06/18] scsi_dh_alua: sanitze sense code handling
Quoted 80 lines · Hannes Reinecke
The only check for a valid sense code is calling
scsi_normalize_sense()
and check the return value. So drop the pointless checks and rely onscsi_normalize_sense()to figure out if the sense code is valid. With that we can also remove the 'senselen' field.Reviewed-by Bart van Assche <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 18 +++++++-----------1 file changed, 7 insertions(+), 11 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +0
-1@@ -73,7 +73,6 @@ struct alua_dh_data { int bufflen; unsigned char transition_tmo; unsigned char sense[SCSI_SENSE_BUFFERSIZE]; -int senselen; struct scsi_device *sdev; activate_complete callback_fn; void *callback_data;@@ -158,14 +157,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h,
rq->sense=h->sense;memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- rq->sense_len = h->senselen =0 ; + rq->sense_len =0 ;
err =blk_execute_rq(rq->q, NULL, rq, 1); if (err ==-EIO) {sdev_printk(KERN_INFO, sdev, "%s: rtpg failed with %x\n", ALUA_DH_NAME, rq->errors);drivers/scsi/device_handler/scsi_dh_alua.c +0
-1- h->senselen = rq->sense_len;err =
SCSI_DH_IO;
}
blk_put_request(rq);drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -194,9 +192,8 @@ static void stpg_endio(struct request *req, int error) goto done; }drivers/scsi/device_handler/scsi_dh_alua.c +0
-2-if (req->sense_len >0 ) { - err = scsi_normalize_sense(h->sense,
SCSI_SENSE_BUFFERSIZE,drivers/scsi/device_handler/scsi_dh_alua.c +2
-1- &sense_hdr); +if (scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , + &sense_hdr)) {if (!err) {
err =SCSI_DH_IO;
goto done;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -265,7 +262,7 @@ static unsigned submit_stpg(struct alua_dh_data *h)
rq->sense=h->sense;memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- rq->sense_len = h->senselen =0 ; + rq->sense_len =0 ;
rq->end_io_data= h;
blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -514,10 +511,9 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
retry:
err =submit_rtpg(sdev, h, rtpg_ext_hdr_req);drivers/scsi/device_handler/scsi_dh_alua.c +0
-2-if (err ==SCSI_DH_IO && h->senselen >0 ) { - err = scsi_normalize_sense(h->sense,
SCSI_SENSE_BUFFERSIZE,drivers/scsi/device_handler/scsi_dh_alua.c +2
-2- &sense_hdr); -if (!err) + if (err == SCSI_DH_IO) { + if (!scsi_normalize_sense(h->sense,
SCSI_SENSE_BUFFERSIZE,drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+ &sense_hdr))
Quoted 3 lines
return
SCSI_DH_IO;
/*
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/18 scsi_dh_alua: use standard logging functions
In reply to Hannes ReineckeUse standard logging functions instead of hand-crafted ones.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +13 -14
@@ -23,6 +23,7 @@#include <linux/delay.h> #include <linux/module.h> #include <scsi/scsi.h> +#include <scsi/scsi_dbg.h> #include <scsi/scsi_eh.h> #include <scsi/scsi_dh.h>
@@ -194,19 +195,14 @@ static void stpg_endio(struct request *req, int error)if (scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , &sense_hdr)) { -if (!err) { - err =SCSI_DH_IO ; - goto done; - } err =alua_check_sense (h->sdev, &sense_hdr);if (err ==ADD_TO_MLQUEUE ) { err =SCSI_DH_RETRY ; goto done; } -sdev_printk (KERN_INFO , h->sdev, -"%s: stpg sense code: %02x/%02x/%02x\n" , -ALUA_DH_NAME , sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); +sdev_printk (KERN_INFO , h->sdev,"%s: stpg failed\n" , +ALUA_DH_NAME ); +scsi_print_sense_hdr (h->sdev,ALUA_DH_NAME , &sense_hdr); err =SCSI_DH_IO ; }else if (error) err =SCSI_DH_IO ;
@@ -532,13 +528,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ } err =alua_check_sense (sdev, &sense_hdr); -if (err ==ADD_TO_MLQUEUE &&time_before (jiffies, expiry)) +if (err ==ADD_TO_MLQUEUE &&time_before (jiffies, expiry)) { +sdev_printk (KERN_ERR , sdev,"%s: rtpg retry\n" , +ALUA_DH_NAME ); +scsi_print_sense_hdr (sdev,ALUA_DH_NAME , &sense_hdr); goto retry; -sdev_printk (KERN_INFO , sdev, -"%s: rtpg sense code %02x/%02x/%02x\n" , -ALUA_DH_NAME , sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); - err =SCSI_DH_IO ; + } +sdev_printk (KERN_ERR , sdev,"%s: rtpg failed\n" , +ALUA_DH_NAME ); +scsi_print_sense_hdr (sdev,ALUA_DH_NAME , &sense_hdr); +return SCSI_DH_IO ; }if (err !=SCSI_DH_OK )return err;
Signature · 1 line
1.8.5.6
Re: [PATCH 07/18] scsi_dh_alua: use standard logging functions
Quoted 73 lines · Hannes Reinecke
Use standard logging functions instead of hand-crafted ones.
Reviewed-by Bart Van Assche <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 27 +++++++++++++-------
-------1 file changed, 13 insertions(+), 14 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +1
-0@@ -23,6 +23,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <scsi/scsi.h> +#include <scsi/scsi_dbg.h> #include <scsi/scsi_eh.h> #include <scsi/scsi_dh.h>drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -194,19 +195,14 @@ static void stpg_endio(struct request *req, int error)
if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) {drivers/scsi/device_handler/scsi_dh_alua.c +0
-4-if (!err) { - err =SCSI_DH_IO ; - goto done; - }err =
alua_check_sense(h->sdev, &sense_hdr); if (err ==ADD_TO_MLQUEUE) {
err =SCSI_DH_RETRY;
goto done;
}drivers/scsi/device_handler/scsi_dh_alua.c +3
-4-sdev_printk (KERN_INFO , h->sdev, - "%s: stpg sense code: %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); +sdev_printk (KERN_INFO , h->sdev,"%s: stpg failed\n" , + ALUA_DH_NAME); + scsi_print_sense_hdr(h->sdev, ALUA_DH_NAME,
&sense_hdr);
err =SCSI_DH_IO;
} else if (error)
err =SCSI_DH_IO;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -532,13 +528,16 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
}
err =alua_check_sense(sdev, &sense_hdr);drivers/scsi/device_handler/scsi_dh_alua.c +0
-1- if (err == ADD_TO_MLQUEUE && time_before(jiffies,expiry))
drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+ if (err == ADD_TO_MLQUEUE && time_before(jiffies,expiry)) {
drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+ sdev_printk(KERN_ERR, sdev, "%s: rtpgretry\n",
drivers/scsi/device_handler/scsi_dh_alua.c +2
-0+ ALUA_DH_NAME); + scsi_print_sense_hdr(sdev, ALUA_DH_NAME,
&sense_hdr);
goto retry;drivers/scsi/device_handler/scsi_dh_alua.c +4
-5-sdev_printk (KERN_INFO , sdev, - "%s: rtpg sense code %02x/%02x/%02x\n", - ALUA_DH_NAME, sense_hdr.sense_key, - sense_hdr.asc, sense_hdr.ascq); - err =SCSI_DH_IO ; + } +sdev_printk (KERN_ERR , sdev,"%s: rtpg failed\n" , + ALUA_DH_NAME); + scsi_print_sense_hdr(sdev, ALUA_DH_NAME,
&sense_hdr);drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+return SCSI_DH_IO ;
Quoted 3 lines
}
if (err !=SCSI_DH_OK)
return err;
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 8/18 scsi_dh_alua: return standard SCSI return codes in submit_rtpg
In reply to Hannes ReineckeFixup submit_rtpg() to always return a standard SCSI return code.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 33 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +17 -16
@@ -138,11 +138,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, bool rtpg_ext_hdr_req) {struct request *rq; -int err =SCSI_DH_RES_TEMP_UNAVAIL ; +int err =0 ; rq =get_alua_req (sdev, h->buff, h->bufflen,READ ); -if (!rq) +if (!rq) { + err =DRIVER_BUSY <<24 ; goto done; + }/* Prepare the command. */ rq->cmd[0 ] =MAINTENANCE_IN ;
@@ -160,13 +162,9 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h,memset (rq->sense,0 ,SCSI_SENSE_BUFFERSIZE ); rq->sense_len =0 ; - err =blk_execute_rq (rq->q,NULL , rq,1 ); -if (err == -EIO ) { -sdev_printk (KERN_INFO , sdev, -"%s: rtpg failed with %x\n" , -ALUA_DH_NAME , rq->errors); - err =SCSI_DH_IO ; - } +blk_execute_rq (rq->q,NULL , rq,1 ); +if (rq->errors) + err = rq->errors;blk_put_request (rq); done:return err;
@@ -493,7 +491,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_struct scsi_sense_hdr sense_hdr;int len, k, off, valid_states =0 ;unsigned char *ucp; -unsigned err; +unsigned err, retval;bool rtpg_ext_hdr_req =1 ;unsigned long expiry, interval =0 ;unsigned int tpg_desc_tbl_off;
@@ -505,12 +503,17 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ expiry =round_jiffies_up (jiffies + h->transition_tmo *HZ ); retry: - err =submit_rtpg (sdev, h, rtpg_ext_hdr_req); - -if (err ==SCSI_DH_IO ) { + retval =submit_rtpg (sdev, h, rtpg_ext_hdr_req); +if (retval) {if (!scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , - &sense_hdr)) + &sense_hdr)) { +sdev_printk (KERN_INFO , sdev, +"%s: rtpg failed, result %d\n" , +ALUA_DH_NAME , retval); +if (driver_byte (retval) ==DRIVER_BUSY ) +return SCSI_DH_DEV_TEMP_BUSY ;return SCSI_DH_IO ; + }/* * submit_rtpg() has failed on existing arrays
@@ -539,8 +542,6 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_scsi_print_sense_hdr (sdev,ALUA_DH_NAME , &sense_hdr);return SCSI_DH_IO ; } -if (err !=SCSI_DH_OK ) -return err; len = (h->buff[0 ] <<24 ) + (h->buff[1 ] <<16 ) + (h->buff[2 ] <<8 ) + h->buff[3 ] +4 ;
Signature · 1 line
1.8.5.6
Re: [PATCH 08/18] scsi_dh_alua: return standard SCSI return codes in submit_rtpg
Quoted 91 lines · Hannes Reinecke
Fixup
submit_rtpg()to always return a standard SCSI return code.Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 33 +++++++++++++++-----
----------1 file changed, 17 insertions(+), 16 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +1
-1@@ -138,11 +138,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, bool rtpg_ext_hdr_req) { struct request *rq; -int err =SCSI_DH_RES_TEMP_UNAVAIL ; +int err =0 ;
rq =get_alua_req(sdev, h->buff, h->bufflen, READ);drivers/scsi/device_handler/scsi_dh_alua.c +2
-1-if (!rq) +if (!rq) { + err =DRIVER_BUSY <<24 ;goto done;
drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+ }
/* Prepare the command. */
rq->cmd[0] =MAINTENANCE_IN;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -160,13 +162,9 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); rq->sense_len = 0;drivers/scsi/device_handler/scsi_dh_alua.c +3
-7- err =blk_execute_rq (rq->q,NULL , rq,1 ); -if (err == -EIO ) { -sdev_printk (KERN_INFO , sdev, - "%s: rtpg failed with %x\n", - ALUA_DH_NAME, rq->errors); - err =SCSI_DH_IO ; - } +blk_execute_rq (rq->q,NULL , rq,1 ); +if (rq->errors) + err = rq->errors;
blk_put_request(rq);
done:
return err;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -493,7 +491,7 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
structscsi_sense_hdrsense_hdr;
int len, k, off,valid_states= 0;
unsigned char *ucp;drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-unsigned err; +unsigned err, retval;bool
rtpg_ext_hdr_req= 1;
unsigned long expiry, interval = 0;
unsigned inttpg_desc_tbl_off;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -505,12 +503,17 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
expiry = round_jiffies_up(jiffies + h-Quoted 1 line
transition_tmo* HZ);
retry:drivers/scsi/device_handler/scsi_dh_alua.c +2
-3- err =submit_rtpg (sdev, h, rtpg_ext_hdr_req); - -if (err ==SCSI_DH_IO ) { + retval =submit_rtpg (sdev, h, rtpg_ext_hdr_req); +if (retval) {if (!scsi_normalize_sense(h->sense,
SCSI_SENSE_BUFFERSIZE,drivers/scsi/device_handler/scsi_dh_alua.c +6
-1- &sense_hdr)) + &sense_hdr)) { +sdev_printk (KERN_INFO , sdev, + "%s: rtpg failed, result %d\n", + ALUA_DH_NAME, retval); +if (driver_byte (retval) ==DRIVER_BUSY ) +return SCSI_DH_DEV_TEMP_BUSY ;return
SCSI_DH_IO;drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+ }
/*
*submit_rtpg()has failed on existing arraysdrivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -539,8 +542,6 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
returnSCSI_DH_IO;
}drivers/scsi/device_handler/scsi_dh_alua.c +0
-2-if (err !=SCSI_DH_OK ) -return err;
Quoted 3 lines
len = (h->buff[0] << 24) + (h->buff[1] << 16) + (h->buff[2] << 8) + h->buff[3] + 4;
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 9/18 scsi_dh_alua: fixup description of stpg_endio()
In reply to Hannes ReineckeFixup copy-and-paste error in the description of stpg_endio().
--- drivers/scsi/device_handler/scsi_dh_alua.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +2 -4
@@ -171,13 +171,11 @@ done: }/* -* alua_stpg - Evaluate SET TARGET GROUP STATES +* stpg_endio - Evaluate SET TARGET GROUP STATES * @sdev: the device to be evaluated * @state: the new target group state * -* Send a SET TARGET GROUP STATES command to the device. -* We only have to test here if we should resubmit the command; -* any other error is assumed as a failure. +* Evaluate a SET TARGET GROUP STATES command response. */ static void stpg_endio (struct request *req,int error) {
Signature · 1 line
1.8.5.6
Re: [PATCH 09/18] scsi_dh_alua: fixup description of stpg_endio()
Quoted 22 lines · Hannes Reinecke
Fixup copy-and-paste error in the description of
stpg_endio().Signed-off-by Hannes Reinecke <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Martin K. Petersen <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 6 ++----1 file changed, 2 insertions(+), 4 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -171,13 +171,11 @@ done: }
/*
- *alua_stpg- Evaluate SET TARGET GROUP STATES
+ *stpg_endio- Evaluate SET TARGET GROUP STATES
* @sdev: the device to be evaluated
* @state: the new target group state
Quoted 8 lines
*
- * Send a SET TARGET GROUP STATES command to the device.
- * We only have to test here if we should resubmit the command;
- * any other error is assumed as a failure.
+ * Evaluate a SET TARGET GROUP STATES command response. */
static voidstpg_endio(struct request *req, int error){
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 10/18 scsi: remove scsi_show_sense_hdr()
In reply to Hannes ReineckeLast caller is gone, so remove it.
--- include/scsi/scsi_dbg.h | 2 -- 1 file changed, 2 deletions(-)
include/scsi/scsi_dbg.h +0 -2
@@ -12,8 +12,6 @@ extern size_t __scsi_format_command(char *, size_t, const unsigned char *, size_t);extern void scsi_show_extd_sense (const struct scsi_device *,const char *,unsigned char ,unsigned char ); -extern void scsi_show_sense_hdr (const struct scsi_device *,const char *, -const struct scsi_sense_hdr *);extern void scsi_print_sense_hdr (const struct scsi_device *,const char *,const struct scsi_sense_hdr *);extern void scsi_print_sense (const struct scsi_cmnd *);
Signature · 1 line
1.8.5.6
Re: [PATCH 10/18] scsi: remove scsi_show_sense_hdr()
Quoted 22 lines · Hannes Reinecke
Last caller is gone, so remove it.
Reviewed-by Bart Van Assche <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Martin K. Petersen <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
include/scsi/scsi_dbg.h | 2 --1 file changed, 2 deletions(-)include/scsi/scsi_dbg.h +0
-0@@ -12,8 +12,6 @@ extern size_t __scsi_format_command(char *, size_t, const unsigned char *, size_t);extern void scsi_show_extd_sense(const struct
scsi_device*, const char *,
unsigned char, unsigned char); -extern void scsi_show_sense_hdr(const structscsi_device*, const char *,include/scsi/scsi_dbg.h +0
-1- const struct scsi_sense_hdr *);
Quoted 4 lines
extern void scsi_print_sense_hdr(const struct
scsi_device*, const char *,
const structscsi_sense_hdr*); extern voidscsi_print_sense(const struct scsi_cmnd *);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 11/18 scsi_dh_alua: use flag for RTPG extended header
In reply to Hannes ReineckeWe should be using a flag when RTPG extended header is not supported, that saves us sending RTPG twice for older arrays.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +7 -8
@@ -59,8 +59,9 @@#define ALUA_FAILOVER_TIMEOUT 60#define ALUA_FAILOVER_RETRIES 5 -/* flags passed from user level */ +/* device handler flags */ #define ALUA_OPTIMIZE_STPG 1 +#define ALUA_RTPG_EXT_HDR_UNSUPP 2struct alua_dh_data {int group_id;
@@ -134,8 +135,7 @@ static struct request *get_alua_req(struct scsi_device *sdev,* submit_rtpg - Issue a REPORT TARGET GROUP STATES command * @sdev: sdev the command should be sent to */ -static unsigned submit_rtpg (struct scsi_device *sdev,struct alua_dh_data *h, -bool rtpg_ext_hdr_req) +static unsigned submit_rtpg (struct scsi_device *sdev,struct alua_dh_data *h) {struct request *rq;int err =0 ;
@@ -148,7 +148,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h,/* Prepare the command. */ rq->cmd[0 ] =MAINTENANCE_IN ; -if (rtpg_ext_hdr_req) +if (!(h->flags &ALUA_RTPG_EXT_HDR_UNSUPP )) rq->cmd[1 ] =MI_REPORT_TARGET_PGS |MI_EXT_HDR_PARAM_FMT ;else rq->cmd[1 ] =MI_REPORT_TARGET_PGS ;
@@ -490,7 +490,6 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_int len, k, off, valid_states =0 ;unsigned char *ucp;unsigned err, retval; -bool rtpg_ext_hdr_req =1 ;unsigned long expiry, interval =0 ;unsigned int tpg_desc_tbl_off;unsigned char orig_transition_tmo;
@@ -501,7 +500,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ expiry =round_jiffies_up (jiffies + h->transition_tmo *HZ ); retry: - retval =submit_rtpg (sdev, h, rtpg_ext_hdr_req); + retval =submit_rtpg (sdev, h);if (retval) {if (!scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , &sense_hdr)) {
@@ -521,10 +520,10 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_* The retry without rtpg_ext_hdr_req set * handles this. */ -if (rtpg_ext_hdr_req ==1 && +if (!(h->flags &ALUA_RTPG_EXT_HDR_UNSUPP ) && sense_hdr.sense_key ==ILLEGAL_REQUEST && sense_hdr.asc ==0x24 && sense_hdr.ascq ==0 ) { - rtpg_ext_hdr_req =0 ; + h->flags |=ALUA_RTPG_EXT_HDR_UNSUPP ; goto retry; }
Signature · 1 line
1.8.5.6
Re: [PATCH 11/18] scsi_dh_alua: use flag for RTPG extended header
Quoted 83 lines · Hannes Reinecke
We should be using a flag when RTPG extended header is not supported, that saves us sending RTPG twice for older arrays.
Reviewed-by Bart Van Assche <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Martin K. Petersen <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 15 +++++++--------1 file changed, 7 insertions(+), 8 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -59,8 +59,9 @@ #define ALUA_FAILOVER_TIMEOUT 60 #define ALUA_FAILOVER_RETRIES 5drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-/* flags passed from user level */ +/* device handler flags */ #define
ALUA_OPTIMIZE_STPG1
+#defineALUA_RTPG_EXT_HDR_UNSUPP2
structalua_dh_data{
intgroup_id;drivers/scsi/device_handler/scsi_dh_alua.c +1
-2@@ -134,8 +135,7 @@ static struct request *get_alua_req(structscsi_device *sdev, * submit_rtpg - Issue a REPORT TARGET GROUP STATES command * @sdev: sdev the command should be sent to */ -static unsigned submit_rtpg(struct scsi_device *sdev, structalua_dh_data *h, - bool rtpg_ext_hdr_req) +static unsigned submit_rtpg(struct scsi_device *sdev, structalua_dh_data *h){
struct request *rq;
int err = 0;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -148,7 +148,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h,
/* Prepare the command. */
rq->cmd[0] =MAINTENANCE_IN;drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-if (rtpg_ext_hdr_req) +if (!(h->flags &ALUA_RTPG_EXT_HDR_UNSUPP ))rq->cmd[1] =
MI_REPORT_TARGET_PGS|MI_EXT_HDR_PARAM_FMT;
else
rq->cmd[1] =MI_REPORT_TARGET_PGS;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -490,7 +490,6 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
int len, k, off,valid_states= 0;
unsigned char *ucp;
unsigned err, retval;drivers/scsi/device_handler/scsi_dh_alua.c +0
-1-bool rtpg_ext_hdr_req =1 ;unsigned long expiry, interval = 0;
unsigned inttpg_desc_tbl_off;
unsigned charorig_transition_tmo;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -501,7 +500,7 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
expiry = round_jiffies_up(jiffies + h-Quoted 1 line
transition_tmo* HZ);
retry:drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- retval =submit_rtpg (sdev, h, rtpg_ext_hdr_req); + retval =submit_rtpg (sdev, h);if (retval) {
if (!scsi_normalize_sense(h->sense,SCSI_SENSE_BUFFERSIZE,
&sense_hdr)) {drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -521,10 +520,10 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
* The retry withoutrtpg_ext_hdr_reqset
* handles this.
*/drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- if (rtpg_ext_hdr_req == 1 && + if (!(h->flags & ALUA_RTPG_EXT_HDR_UNSUPP) &&sense_hdr.sense_key ==
ILLEGAL_REQUEST&& sense_hdr.asc ==0x24&& sense_hdr.ascq == 0) {drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- rtpg_ext_hdr_req =0 ; + h->flags |=ALUA_RTPG_EXT_HDR_UNSUPP ;
Quoted 3 lines
goto retry;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 12/18 scsi_dh_alua: use unaligned access macros
In reply to Hannes ReineckeUse 'get_unaligned_XX' and 'put_unaligned_XX' instead of open-coding it.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +8 -15
@@ -22,6 +22,7 @@#include <linux/slab.h> #include <linux/delay.h> #include <linux/module.h> +#include <asm/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_dbg.h> #include <scsi/scsi_eh.h>
@@ -152,10 +153,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) rq->cmd[1 ] =MI_REPORT_TARGET_PGS |MI_EXT_HDR_PARAM_FMT ; else rq->cmd[1] = MI_REPORT_TARGET_PGS; - rq->cmd[6 ] = (h->bufflen >>24 ) &0xff ; - rq->cmd[7 ] = (h->bufflen >>16 ) &0xff ; - rq->cmd[8 ] = (h->bufflen >>8 ) &0xff ; - rq->cmd[9 ] = h->bufflen &0xff ; +put_unaligned_be32 (h->bufflen, &rq->cmd[6 ]); rq->cmd_len =COMMAND_SIZE (MAINTENANCE_IN ); rq->sense = h->sense;
@@ -236,8 +234,7 @@ static unsigned submit_stpg(struct alua_dh_data *h)/* Prepare the data buffer */ memset (h->buff,0 , stpg_len); h->buff[4 ] =TPGS_STATE_OPTIMIZED &0x0f ; - h->buff[6 ] = (h->group_id >>8 ) &0xff ; - h->buff[7 ] = h->group_id &0xff ; +put_unaligned_be16 (h->group_id, &h->buff[6 ]); rq =get_alua_req (sdev, h->buff, stpg_len,WRITE );if (!rq)
@@ -246,10 +243,7 @@ static unsigned submit_stpg(struct alua_dh_data *h)/* Prepare the command. */ rq->cmd[0 ] =MAINTENANCE_OUT ; rq->cmd[1 ] =MO_SET_TARGET_PGS ; - rq->cmd[6 ] = (stpg_len >>24 ) &0xff ; - rq->cmd[7 ] = (stpg_len >>16 ) &0xff ; - rq->cmd[8 ] = (stpg_len >>8 ) &0xff ; - rq->cmd[9 ] = stpg_len &0xff ; +put_unaligned_be32 (stpg_len, &rq->cmd[6 ]); rq->cmd_len =COMMAND_SIZE (MAINTENANCE_OUT ); rq->sense = h->sense;
@@ -343,11 +337,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h)switch (d[1 ] &0xf ) {case 0x4 :/* Relative target port */ - h->rel_port = (d[6 ] <<8 ) + d[7 ]; + h->rel_port =get_unaligned_be16 (&d[6 ]);break ;case 0x5 :/* Target port group */ - h->group_id = (d[6 ] <<8 ) + d[7 ]; + h->group_id =get_unaligned_be16 (&d[6 ]);break ;default :break ;
@@ -540,8 +534,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_return SCSI_DH_IO ; } - len = (h->buff[0 ] <<24 ) + (h->buff[1 ] <<16 ) + - (h->buff[2 ] <<8 ) + h->buff[3 ] +4 ; + len =get_unaligned_be32 (&h->buff[0 ]) +4 ;if (len > h->bufflen) {/* Resubmit with the correct length */
@@ -576,7 +569,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ k < len; k += off, ucp += off) { -if (h->group_id == (ucp[2 ] <<8 ) + ucp[3 ]) { +if (h->group_id ==get_unaligned_be16 (&ucp[2 ])) { h->state = ucp[0 ] &0x0f ; h->pref = ucp[0 ] >>7 ; valid_states = ucp[1 ];
Signature · 1 line
1.8.5.6
Re: [PATCH 12/18] scsi_dh_alua: use unaligned access macros
Quoted 95 lines · Hannes Reinecke
Use '
get_unaligned_XX' and 'put_unaligned_XX' instead of open-coding it.Reviewed-by Martin K. Petersen <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 23 ++++++++----------
-----1 file changed, 8 insertions(+), 15 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +1
-0@@ -22,6 +22,7 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/module.h> +#include <asm/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_dbg.h> #include <scsi/scsi_eh.h>@@ -152,10 +153,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)rq->cmd[1] =
MI_REPORT_TARGET_PGS|MI_EXT_HDR_PARAM_FMT;
else
rq->cmd[1] =MI_REPORT_TARGET_PGS;drivers/scsi/device_handler/scsi_dh_alua.c +1
-4- rq->cmd[6 ] = (h->bufflen >>24 ) &0xff ; - rq->cmd[7 ] = (h->bufflen >>16 ) &0xff ; - rq->cmd[8] = (h->bufflen >> 8) & 0xff; - rq->cmd[9 ] = h->bufflen &0xff ; +put_unaligned_be32 (h->bufflen, &rq->cmd[6 ]);
rq->cmd_len=COMMAND_SIZE(MAINTENANCE_IN);
rq->sense=h->sense;drivers/scsi/device_handler/scsi_dh_alua.c +1
-2@@ -236,8 +234,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) /* Prepare the data buffer */ memset(h->buff, 0, stpg_len); h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f; - h->buff[6 ] = (h->group_id >>8 ) &0xff ; - h->buff[7 ] = h->group_id &0xff ; +put_unaligned_be16 (h->group_id, &h->buff[6 ]);
rq =get_alua_req(sdev, h->buff, stpg_len, WRITE); if (!rq)drivers/scsi/device_handler/scsi_dh_alua.c +1
-4@@ -246,10 +243,7 @@ static unsigned submit_stpg(struct alua_dh_data *h) /* Prepare the command. */ rq->cmd[0] = MAINTENANCE_OUT; rq->cmd[1] = MO_SET_TARGET_PGS; - rq->cmd[6 ] = (stpg_len >>24 ) &0xff ; - rq->cmd[7 ] = (stpg_len >>16 ) &0xff ; - rq->cmd[8] = (stpg_len >> 8) & 0xff; - rq->cmd[9 ] = stpg_len &0xff ; +put_unaligned_be32 (stpg_len, &rq->cmd[6 ]); rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
rq->sense=h->sense;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -343,11 +337,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) switch (d[1] & 0xf) {case
0x4:
/* Relative target port */drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- h->rel_port = (d[6 ] <<8 ) + d[7 ]; + h->rel_port =get_unaligned_be16 (&d[6 ]);break;
case0x5:
/* Target port group */drivers/scsi/device_handler/scsi_dh_alua.c +1
-1- h->group_id = (d[6 ] <<8 ) + d[7 ]; + h->group_id =get_unaligned_be16 (&d[6 ]);break;
default:
break;drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -540,8 +534,7 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
returnSCSI_DH_IO;
}drivers/scsi/device_handler/scsi_dh_alua.c +1
-2- len = (h->buff[0 ] <<24 ) + (h->buff[1 ] <<16 ) + - (h->buff[2 ] <<8 ) + h->buff[3 ] +4 ; + len =get_unaligned_be32 (&h->buff[0 ]) +4 ;
if (len >h->bufflen) {
/* Resubmit with the correct length */drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -576,7 +569,7 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
k < len;
k += off, ucp += off) {drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-if (h->group_id == (ucp[2 ] <<8 ) + ucp[3 ]) { +if (h->group_id ==get_unaligned_be16 (&ucp[2 ])) {
Quoted 3 lines
h->state= ucp[0] &0x0f;
h->pref= ucp[0] >> 7;
valid_states= ucp[1];
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 13/18 scsi_dh_alua: rework alua_check_tpgs() to return the tpgs mode
In reply to Hannes ReineckeInstead of returning an error code in alua_check_tpgs() we should rather return the tpgs mode directly and have a cleaner syntax.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +11 -14
@@ -262,24 +262,23 @@ static unsigned submit_stpg(struct alua_dh_data *h)* Examine the TPGS setting of the sdev to find out if ALUA * is supported. */ -static int alua_check_tpgs (struct scsi_device *sdev,struct alua_dh_data *h) +static int alua_check_tpgs (struct scsi_device *sdev) { -int err =SCSI_DH_OK ; +int tpgs =TPGS_MODE_NONE ;/* * ALUA support for non-disk devices is fraught with * difficulties, so disable it for now. */ if (sdev->type !=TYPE_DISK ) { - h->tpgs =TPGS_MODE_NONE ;sdev_printk (KERN_INFO , sdev,"%s: disable for non-disk devices\n" ,ALUA_DH_NAME ); -return SCSI_DH_DEV_UNSUPP ; +return tpgs; } - h->tpgs =scsi_device_tpgs (sdev); -switch (h->tpgs) { + tpgs =scsi_device_tpgs (sdev); +switch (tpgs) {case TPGS_MODE_EXPLICIT |TPGS_MODE_IMPLICIT : sdev_printk(KERN_INFO, sdev, "%s: supports implicit and explicit TPGS\n",
@@ -296,18 +295,16 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h)case TPGS_MODE_NONE :sdev_printk (KERN_INFO , sdev,"%s: not supported\n" ,ALUA_DH_NAME ); - err =SCSI_DH_DEV_UNSUPP ;break ;default :sdev_printk (KERN_INFO , sdev,"%s: unsupported TPGS setting %d\n" , -ALUA_DH_NAME , h->tpgs); - h->tpgs =TPGS_MODE_NONE ; - err =SCSI_DH_DEV_UNSUPP ; +ALUA_DH_NAME , tpgs); + tpgs =TPGS_MODE_NONE ;break ; } -return err; +return tpgs; }/*
@@ -627,10 +624,10 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_*/ static int alua_initialize (struct scsi_device *sdev,struct alua_dh_data *h) { -int err; +int err =SCSI_DH_DEV_UNSUPP ; - err =alua_check_tpgs (sdev, h); -if (err !=SCSI_DH_OK ) + h->tpgs =alua_check_tpgs (sdev); +if (h->tpgs ==TPGS_MODE_NONE ) goto out; err =alua_check_vpd (sdev, h);
Signature · 1 line
1.8.5.6
Re: [PATCH 13/18] scsi_dh_alua: rework alua_check_tpgs() to return the tpgs mode
Quoted 83 lines · Hannes Reinecke
Instead of returning an error code in
alua_check_tpgs()we should rather return the tpgs mode directly and have a cleaner syntax.Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 25 +++++++++++---------
-----1 file changed, 11 insertions(+), 14 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +2
-2@@ -262,24 +262,23 @@ static unsigned submit_stpg(struct alua_dh_data*h) * Examine the TPGS setting of the sdev to find out if ALUA * is supported. */ -static int alua_check_tpgs (struct scsi_device *sdev,struct alua_dh_data *h) +static int alua_check_tpgs (struct scsi_device *sdev) { -int err =SCSI_DH_OK ; +int tpgs =TPGS_MODE_NONE ;
/*
* ALUA support for non-disk devices is fraught with
* difficulties, so disable it for now.
*/
if (sdev->type!=TYPE_DISK) {drivers/scsi/device_handler/scsi_dh_alua.c +0
-1- h->tpgs =TPGS_MODE_NONE ;sdev_printk(KERN_INFO, sdev,
"%s: disable for non-disk devices\n",ALUA_DH_NAME);drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-return SCSI_DH_DEV_UNSUPP ; +return tpgs;}
drivers/scsi/device_handler/scsi_dh_alua.c +2
-2- h->tpgs =scsi_device_tpgs (sdev); -switch (h->tpgs) { + tpgs =scsi_device_tpgs (sdev); +switch (tpgs) {case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
sdev_printk(KERN_INFO, sdev,
"%s: supports implicit and explicit TPGS\n",drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -296,18 +295,16 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct alua_dh_data *h)case
TPGS_MODE_NONE:
sdev_printk(KERN_INFO, sdev, "%s: not supported\n", ALUA_DH_NAME);drivers/scsi/device_handler/scsi_dh_alua.c +0
-1- err =SCSI_DH_DEV_UNSUPP ;break;
default:
sdev_printk(KERN_INFO, sdev,
"%s: unsupported TPGS setting %d\n",drivers/scsi/device_handler/scsi_dh_alua.c +2
-3- ALUA_DH_NAME, h->tpgs); - h->tpgs =TPGS_MODE_NONE ; - err =SCSI_DH_DEV_UNSUPP ; + ALUA_DH_NAME, tpgs); + tpgs =TPGS_MODE_NONE ;break;
}drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-return err; +return tpgs;}
/*drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -627,10 +624,10 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
*/
static intalua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)
{drivers/scsi/device_handler/scsi_dh_alua.c +1
-1-int err; +int err =SCSI_DH_DEV_UNSUPP ;drivers/scsi/device_handler/scsi_dh_alua.c +2
-2- err =alua_check_tpgs (sdev, h); -if (err !=SCSI_DH_OK ) + h->tpgs =alua_check_tpgs (sdev); +if (h->tpgs ==TPGS_MODE_NONE )
Quoted 3 lines
goto out;
err =alua_check_vpd(sdev, h);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 14/18 scsi_dh_alua: simplify sense code handling
In reply to Hannes ReineckeMost sense code is already handled in the generic code, so we shouldn't be adding special cases here. However, when doing so we need to check for unit attention whenever we're sending an internal command.
--- drivers/scsi/device_handler/scsi_dh_alua.c | 45 +++++++++++------------------- 1 file changed, 17 insertions(+), 28 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +17 -28
@@ -85,7 +85,6 @@ struct alua_dh_data {#define ALUA_POLICY_SWITCH_ALL 1static char print_alua_state (int ); -static int alua_check_sense (struct scsi_device *,struct scsi_sense_hdr *);static int realloc_buffer (struct alua_dh_data *h,unsigned len) {
@@ -189,8 +188,13 @@ static void stpg_endio(struct request *req, int error)if (scsi_normalize_sense (h->sense,SCSI_SENSE_BUFFERSIZE , &sense_hdr)) { - err =alua_check_sense (h->sdev, &sense_hdr); -if (err ==ADD_TO_MLQUEUE ) { +if (sense_hdr.sense_key ==NOT_READY && + sense_hdr.asc ==0x04 && sense_hdr.ascq ==0x0a ) { +/* ALUA state transition already in progress */ + err =SCSI_DH_OK ; + goto done; + } +if (sense_hdr.sense_key ==UNIT_ATTENTION ) { err =SCSI_DH_RETRY ; goto done; }
@@ -399,28 +403,6 @@ static int alua_check_sense(struct scsi_device *sdev,* LUN Not Accessible - ALUA state transition */ return ADD_TO_MLQUEUE ; -if (sense_hdr->asc ==0x04 && sense_hdr->ascq ==0x0b ) -/* -* LUN Not Accessible -- Target port in standby state -*/ -return SUCCESS ; -if (sense_hdr->asc ==0x04 && sense_hdr->ascq ==0x0c ) -/* -* LUN Not Accessible -- Target port in unavailable state -*/ -return SUCCESS ; -if (sense_hdr->asc ==0x04 && sense_hdr->ascq ==0x12 ) -/* -* LUN Not Ready -- Offline -*/ -return SUCCESS ; -if (sdev->allow_restart && - sense_hdr->asc ==0x04 && sense_hdr->ascq ==0x02 ) -/* -* if the device is not started, we need to wake -* the error handler to start the motor -*/ -return FAILED ;break ;case UNIT_ATTENTION :if (sense_hdr->asc ==0x29 && sense_hdr->ascq ==0x00 )
@@ -517,9 +499,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_ h->flags |=ALUA_RTPG_EXT_HDR_UNSUPP ; goto retry; } - - err =alua_check_sense (sdev, &sense_hdr); -if (err ==ADD_TO_MLQUEUE &&time_before (jiffies, expiry)) { +/* +* Retry on ALUA state transition or if any +* UNIT ATTENTION occurred. +*/ +if (sense_hdr.sense_key ==NOT_READY && + sense_hdr.asc ==0x04 && sense_hdr.ascq ==0x0a ) + err =SCSI_DH_RETRY ; +else if (sense_hdr.sense_key ==UNIT_ATTENTION ) + err =SCSI_DH_RETRY ; +if (err ==SCSI_DH_RETRY &&time_before (jiffies, expiry)) {sdev_printk (KERN_ERR , sdev,"%s: rtpg retry\n" ,ALUA_DH_NAME );scsi_print_sense_hdr (sdev,ALUA_DH_NAME , &sense_hdr);
Signature · 1 line
1.8.5.6
Re: [PATCH 14/18] scsi_dh_alua: simplify sense code handling
Quoted 105 lines · Hannes Reinecke
Most sense code is already handled in the generic code, so we shouldn't be adding special cases here. However, when doing so we need to check for unit attention whenever we're sending an internal command.
Reviewed-by Ewan Milne <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 45 +++++++++++---------
----------1 file changed, 17 insertions(+), 28 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -85,7 +85,6 @@ struct alua_dh_data { #define ALUA_POLICY_SWITCH_ALL 1
static charprint_alua_state(int);
-static intalua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
static intrealloc_buffer(struct alua_dh_data *h, unsigned len){drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -189,8 +188,13 @@ static void stpg_endio(struct request *req, int error)
if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) {drivers/scsi/device_handler/scsi_dh_alua.c +2
-2- err =alua_check_sense (h->sdev, &sense_hdr); -if (err ==ADD_TO_MLQUEUE ) { +if (sense_hdr.sense_key ==NOT_READY && + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a){
drivers/scsi/device_handler/scsi_dh_alua.c +1
-0+/* ALUA state transition already in progress */
drivers/scsi/device_handler/scsi_dh_alua.c +4
-0+ err =SCSI_DH_OK ; + goto done; + } +if (sense_hdr.sense_key ==UNIT_ATTENTION ) {err =
SCSI_DH_RETRY; goto done;
}drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -399,28 +403,6 @@ static int alua_check_sense(struct scsi_device *sdev, * LUN Not Accessible - ALUA statetransition
*/
returnADD_TO_MLQUEUE;drivers/scsi/device_handler/scsi_dh_alua.c +0
-1- if (sense_hdr->asc == 0x04 && sense_hdr->ascq ==
0x0b)drivers/scsi/device_handler/scsi_dh_alua.c +0
-2-/* -* LUN Not Accessible -- Target port in standby state
drivers/scsi/device_handler/scsi_dh_alua.c +0
-3-*/ -return SUCCESS ; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq ==
0x0c)drivers/scsi/device_handler/scsi_dh_alua.c +0
-2-/* -* LUN Not Accessible -- Target port in unavailable state
drivers/scsi/device_handler/scsi_dh_alua.c +0
-3-*/ -return SUCCESS ; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq ==
0x12)drivers/scsi/device_handler/scsi_dh_alua.c +0
-6-/* -* LUN Not Ready -- Offline -*/ -return SUCCESS ; -if (sdev->allow_restart && - sense_hdr->asc == 0x04 && sense_hdr->ascq ==
0x02)drivers/scsi/device_handler/scsi_dh_alua.c +0
-2-/* -* if the device is not started, we need to wake
drivers/scsi/device_handler/scsi_dh_alua.c +0
-3-* the error handler to start the motor -*/ -return FAILED ;break;
caseUNIT_ATTENTION:
if (sense_hdr->asc==0x29&&sense_hdr->ascq==0x00)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -517,9 +499,16 @@ static int alua_rtpg(struct scsi_device *sdev,struct
alua_dh_data*h, intwait_
h->flags|=ALUA_RTPG_EXT_HDR_UNSUPP; goto retry;
}drivers/scsi/device_handler/scsi_dh_alua.c +0
-3- - err =alua_check_sense (sdev, &sense_hdr); - if (err == ADD_TO_MLQUEUE && time_before(jiffies,expiry)) {
drivers/scsi/device_handler/scsi_dh_alua.c +10
-0+/* +* Retry on ALUA state transition or if any +* UNIT ATTENTION occurred. +*/ +if (sense_hdr.sense_key ==NOT_READY && + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) + err =SCSI_DH_RETRY ; +else if (sense_hdr.sense_key ==UNIT_ATTENTION ) + err =SCSI_DH_RETRY ; + if (err == SCSI_DH_RETRY && time_before(jiffies,
Quoted 6 lines
expiry)) {
sdev_printk(KERN_ERR, sdev, "%s: rtpg retry\n",
ALUA_DH_NAME);scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 15/18 scsi: Add scsi_vpd_lun_id()
In reply to Hannes ReineckeAdd a function scsi_vpd_lun_id() to return a unique device identifcation based on the designation descriptors of VPD page 0x83.
As devices might implement several descriptors the order of preference is:
- NAA IEE Registered Extended
- EUI-64 based 16-byte
- EUI-64 based 12-byte
- NAA IEEE Registered
- NAA IEEE Extended
A SCSI name string descriptor is preferred to all of them if the identification is longer than 16 bytes.
The returned unique device identification will be formatted as a SCSI Name string to avoid clashes between different designator types.
--- drivers/scsi/scsi_lib.c | 140 +++++++++++++++++++++++++++++++++++++++++++++ include/scsi/scsi_device.h | 1 + 2 files changed, 141 insertions(+)
drivers/scsi/scsi_lib.c +140 -0
@@ -3154,3 +3154,143 @@ void sdev_enable_disk_events(struct scsi_device *sdev)atomic_dec (&sdev->disk_events_disable_depth); }EXPORT_SYMBOL (sdev_enable_disk_events); + +/* +* scsi_vpd_lun_id - return a unique device identification +* @sdev: SCSI device +* @id: buffer for the identification +* @id_len: length of the buffer +* +* Copies a unique device identification into @id based +* on the information in the VPD page 0x83 of the device. +* The string will be formatted as a SCSI name string. +* +* Returns the length of the identification or error on failure. +* If the identifier is longer than the supplied buffer the actual +* identifier length is returned and the buffer is not zero-padded. +*/ +int scsi_vpd_lun_id (struct scsi_device *sdev,char *id,size_t id_len) +{ +u8 cur_id_type =0xff ; +u8 cur_id_size =0 ; +unsigned char *d, *cur_id_str; +unsigned char __rcu *vpd_pg83; +int id_size = -EINVAL ; + +rcu_read_lock (); + vpd_pg83 =rcu_dereference (sdev->vpd_pg83); +if (!vpd_pg83) { +rcu_read_unlock (); +return -ENXIO ; + } + +/* +* Look for the correct descriptor. +* Order of preference for lun descriptor: +* - SCSI name string +* - NAA IEEE Registered Extended +* - EUI-64 based 16-byte +* - EUI-64 based 12-byte +* - NAA IEEE Registered +* - NAA IEEE Extended +* as longer descriptors reduce the likelyhood +* of identification clashes. +*/ + +/* The id string must be at least 20 bytes + terminating NULL byte */ +if (id_len <21 ) { +rcu_read_unlock (); +return -EINVAL ; + } + +memset (id,0 , id_len); + d = vpd_pg83 +4 ; +while (d < vpd_pg83 + sdev->vpd_pg83_len) { +/* Skip designators not referring to the LUN */ +if ((d[1 ] &0x30 ) !=0x00 ) + goto next_desig; + +switch (d[1 ] &0xf ) { +case 0x2 : +/* EUI-64 */ +if (cur_id_size > d[3 ]) +break ; +/* Prefer NAA IEEE Registered Extended */ +if (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 ; +switch (cur_id_size) { +case 8 : + id_size =snprintf (id, id_len, +"eui.%8phN" , + cur_id_str); +break ; +case 12 : + id_size =snprintf (id, id_len, +"eui.%12phN" , + cur_id_str); +break ; +case 16 : + id_size =snprintf (id, id_len, +"eui.%16phN" , + cur_id_str); +break ; +default : + cur_id_size =0 ; +break ; + } +break ; +case 0x3 : +/* NAA */ +if (cur_id_size > d[3 ]) +break ; + cur_id_size = d[3 ]; + cur_id_str = d +4 ; + cur_id_type = d[1 ] &0xf ; +switch (cur_id_size) { +case 8 : + id_size =snprintf (id, id_len, +"naa.%8phN" , + cur_id_str); +break ; +case 16 : + id_size =snprintf (id, id_len, +"naa.%16phN" , + cur_id_str); +break ; +default : + cur_id_size =0 ; +break ; + } +break ; +case 0x8 : +/* SCSI name string */ +if (cur_id_size +4 > d[3 ]) +break ; +/* Prefer others for truncated descriptor */ +if (cur_id_size && d[3 ] > id_len) +break ; + cur_id_size = id_size = d[3 ]; + cur_id_str = d +4 ; + cur_id_type = d[1 ] &0xf ; +if (cur_id_size >= id_len) + cur_id_size = id_len -1 ; +memcpy (id, cur_id_str, cur_id_size); +/* Decrease priority for truncated descriptor */ +if (cur_id_size != id_size) + cur_id_size =6 ; +break ; +default : +break ; + } +next_desig: + d += d[3 ] +4 ; + } +rcu_read_unlock (); + +return id_size; +} +EXPORT_SYMBOL (scsi_vpd_lun_id);
include/scsi/scsi_device.h +1 -0
@@ -415,6 +415,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev, }extern void sdev_disable_disk_events (struct scsi_device *sdev);extern void sdev_enable_disk_events (struct scsi_device *sdev); +extern int scsi_vpd_lun_id (struct scsi_device *,char *,size_t );#ifdef CONFIG_PM extern int scsi_autopm_get_device (struct scsi_device *);
Signature · 1 line
1.8.5.6
Re: [PATCH 15/18] scsi: Add scsi_vpd_lun_id()
Quoted 189 lines · Hannes Reinecke
Add a function
scsi_vpd_lun_id()to return a unique device identifcation based on the designation descriptors of VPD page0x83.As devices might implement several descriptors the order of preference is:
- NAA IEE Registered Extended
- EUI-64 based 16-byte
- EUI-64 based 12-byte
- NAA IEEE Registered
- NAA IEEE Extended
A SCSI name string descriptor is preferred to all of them if the identification is longer than 16 bytes.The returned unique device identification will be formatted as a SCSI Name string to avoid clashes between different designator types.
Reviewed-by Ewan Milne <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/scsi_lib.c | 140
+++++++++++++++++++++++++++++++++++++++++++++
include/scsi/scsi_device.h | 1 +2 files changed, 141 insertions(+)drivers/scsi/scsi_lib.c +0
-0@@ -3154,3 +3154,143 @@ void sdev_enable_disk_events(struct scsi_device *sdev) atomic_dec(&sdev->disk_events_disable_depth); }EXPORT_SYMBOL(sdev_enable_disk_events);
drivers/scsi/scsi_lib.c +16
-0+ +/* +* scsi_vpd_lun_id - return a unique device identification +* @sdev: SCSI device +* @id: buffer for the identification +* @id_len: length of the buffer +* +* Copies a unique device identification into @id based +* on the information in the VPD page 0x83 of the device. +* The string will be formatted as a SCSI name string. +* +* Returns the length of the identification or error on failure. +* If the identifier is longer than the supplied buffer the actual +* identifier length is returned and the buffer is not zero-padded. +*/ +int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t
id_len)drivers/scsi/scsi_lib.c +28
-0+{ +u8 cur_id_type =0xff ; +u8 cur_id_size =0 ; +unsigned char *d, *cur_id_str; +unsigned char __rcu *vpd_pg83; +int id_size = -EINVAL ; + +rcu_read_lock (); + vpd_pg83 =rcu_dereference (sdev->vpd_pg83); +if (!vpd_pg83) { +rcu_read_unlock (); +return -ENXIO ; + } + +/* +* Look for the correct descriptor. +* Order of preference for lun descriptor: +* - SCSI name string +* - NAA IEEE Registered Extended +* - EUI-64 based 16-byte +* - EUI-64 based 12-byte +* - NAA IEEE Registered +* - NAA IEEE Extended +* as longer descriptors reduce the likelyhood +* of identification clashes. +*/ + +/* The id string must be at least 20 bytes + terminating NULL byte */
drivers/scsi/scsi_lib.c +82
-0+if (id_len <21 ) { +rcu_read_unlock (); +return -EINVAL ; + } + +memset (id,0 , id_len); + d = vpd_pg83 +4 ; +while (d < vpd_pg83 + sdev->vpd_pg83_len) { +/* Skip designators not referring to the LUN */ +if ((d[1 ] &0x30 ) !=0x00 ) + goto next_desig; + +switch (d[1 ] &0xf ) { +case 0x2 : +/* EUI-64 */ +if (cur_id_size > d[3 ]) +break ; +/* Prefer NAA IEEE Registered Extended */ +if (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 ; +switch (cur_id_size) { +case 8 : + id_size =snprintf (id, id_len, + "eui.%8phN", + cur_id_str); +break ; +case 12 : + id_size =snprintf (id, id_len, + "eui.%12phN", + cur_id_str); +break ; +case 16 : + id_size =snprintf (id, id_len, + "eui.%16phN", + cur_id_str); +break ; +default : + cur_id_size =0 ; +break ; + } +break ; +case 0x3 : +/* NAA */ +if (cur_id_size > d[3 ]) +break ; + cur_id_size = d[3 ]; + cur_id_str = d +4 ; + cur_id_type = d[1 ] &0xf ; +switch (cur_id_size) { +case 8 : + id_size =snprintf (id, id_len, + "naa.%8phN", + cur_id_str); +break ; +case 16 : + id_size =snprintf (id, id_len, + "naa.%16phN", + cur_id_str); +break ; +default : + cur_id_size =0 ; +break ; + } +break ; +case 0x8 : +/* SCSI name string */ +if (cur_id_size +4 > d[3 ]) +break ; +/* Prefer others for truncated descriptor */ +if (cur_id_size && d[3 ] > id_len) +break ; + cur_id_size = id_size = d[3 ]; + cur_id_str = d +4 ; + cur_id_type = d[1 ] &0xf ; +if (cur_id_size >= id_len) + cur_id_size = id_len -1 ; +memcpy (id, cur_id_str, cur_id_size); +/* Decrease priority for truncated descriptor */
drivers/scsi/scsi_lib.c +14
-0+if (cur_id_size != id_size) + cur_id_size =6 ; +break ; +default : +break ; + } +next_desig: + d += d[3 ] +4 ; + } +rcu_read_unlock (); + +return id_size; +} +EXPORT_SYMBOL (scsi_vpd_lun_id);include/scsi/scsi_device.h +1
-0@@ -415,6 +415,7 @@ static inline int scsi_execute_req(structscsi_device *sdev, } extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); +extern int scsi_vpd_lun_id (struct scsi_device *,char *,size_t );
Quoted 3 lines
#ifdefCONFIG_PM
extern intscsi_autopm_get_device(struct scsi_device *);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 16/18 scsi: export 'device_id' to sysfs
In reply to Hannes ReineckeUse scsi_vpd_lun_id() to export the device id to sysfs.
--- drivers/scsi/scsi_sysfs.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/scsi/scsi_sysfs.c +17 -0
@@ -903,6 +903,22 @@ sdev_show_function(queue_depth, "%d\n"); static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth, sdev_store_queue_depth); +static ssize_t +sdev_show_device_id (struct device *dev,struct device_attribute *attr, +char *buf) +{ +struct scsi_device *sdev =to_scsi_device (dev); +ssize_t count; + + count =scsi_vpd_lun_id (sdev, buf,PAGE_SIZE ); +if (count >0 ) { + buf[count] ='\n' ; + count++; + } +return count; +} +static DEVICE_ATTR(device_id, S_IRUGO, sdev_show_device_id, NULL); +#ifdef CONFIG_SCSI_DH static ssize_t sdev_show_dh_state(struct device *dev, struct device_attribute *attr,
@@ -1026,6 +1042,7 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_modalias.attr, &dev_attr_queue_depth.attr, &dev_attr_queue_type.attr, + &dev_attr_device_id.attr, #ifdef CONFIG_SCSI_DH &dev_attr_dh_state.attr, #endif
Signature · 1 line
1.8.5.6
Re: [PATCH 16/18] scsi: export 'device_id' to sysfs
Quoted 38 lines · Hannes Reinecke
Use
scsi_vpd_lun_id()to export the device id to sysfs.Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/scsi_sysfs.c | 17 +++++++++++++++++1 file changed, 17 insertions(+)drivers/scsi/scsi_sysfs.c +0
-0@@ -903,6 +903,22 @@ sdev_show_function(queue_depth, "%d\n"); static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth, sdev_store_queue_depth);drivers/scsi/scsi_sysfs.c +2
-0+static ssize_t +sdev_show_device_id(struct device *dev, struct device_attribute*attr,
drivers/scsi/scsi_sysfs.c +14
-0+ char *buf) +{ +struct scsi_device *sdev =to_scsi_device (dev); +ssize_t count; + + count =scsi_vpd_lun_id (sdev, buf,PAGE_SIZE ); +if (count >0 ) { + buf[count] ='\n' ; + count++; + } +return count; +} +static DEVICE_ATTR(device_id, S_IRUGO, sdev_show_device_id, NULL); +#ifdef
CONFIG_SCSI_DH
staticssize_t
sdev_show_dh_state(struct device *dev, structdevice_attribute*attr,
drivers/scsi/scsi_sysfs.c static struct attribute *scsi_sdev_attrs[] = { · line 1048
Quoted 7 lines
drivers/scsi/scsi_sysfs.c +1
-0@@ -1026,6 +1042,7 @@ static struct attribute *scsi_sdev_attrs[] = { &dev_attr_modalias.attr, &dev_attr_queue_depth.attr, &dev_attr_queue_type.attr, + &dev_attr_device_id.attr, #ifdef CONFIG_SCSI_DH &dev_attr_dh_state.attr, #endif
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 17/18 scsi: Add scsi_vpd_tpg_id()
In reply to Hannes ReineckeImplement scsi_vpd_tpg_id() to extract the target
port group id and the relative port id from
SCSI VPD page 0x83.
--- drivers/scsi/scsi_lib.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ include/scsi/scsi_device.h | 1 + 2 files changed, 49 insertions(+)
drivers/scsi/scsi_lib.c +48 -0
@@ -23,6 +23,7 @@#include <linux/scatterlist.h> #include <linux/blk-mq.h> #include <linux/ratelimit.h> +#include <asm/unaligned.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h>
@@ -3294,3 +3295,50 @@ next_desig:return id_size; }EXPORT_SYMBOL (scsi_vpd_lun_id); + +/* +* scsi_vpd_tpg_id - return a target port group identifier +* @sdev: SCSI device +* +* Returns the Target Port Group identifier from the information +* froom VPD page 0x83 of the device. +* +* Returns the identifier or error on failure. +*/ +int scsi_vpd_tpg_id (struct scsi_device *sdev,int *rel_id) +{ +unsigned char *d; +unsigned char __rcu *vpd_pg83; +int group_id = -EAGAIN , rel_port =-1 ; + +rcu_read_lock (); + vpd_pg83 =rcu_dereference (sdev->vpd_pg83); +if (!vpd_pg83) { +rcu_read_unlock (); +return -ENXIO ; + } + + d = sdev->vpd_pg83 +4 ; +while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) { +switch (d[1 ] &0xf ) { +case 0x4 : +/* Relative target port */ + rel_port =get_unaligned_be16 (&d[6 ]); +break ; +case 0x5 : +/* Target port group */ + group_id =get_unaligned_be16 (&d[6 ]); +break ; +default : +break ; + } + d += d[3 ] +4 ; + } +rcu_read_unlock (); + +if (group_id >=0 && rel_id && rel_port !=-1 ) + *rel_id = rel_port; + +return group_id; +} +EXPORT_SYMBOL (scsi_vpd_tpg_id);
include/scsi/scsi_device.h +1 -0
@@ -416,6 +416,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev,extern void sdev_disable_disk_events (struct scsi_device *sdev);extern void sdev_enable_disk_events (struct scsi_device *sdev);extern int scsi_vpd_lun_id (struct scsi_device *,char *,size_t ); +extern int scsi_vpd_tpg_id (struct scsi_device *,int *);#ifdef CONFIG_PM extern int scsi_autopm_get_device (struct scsi_device *);
Signature · 1 line
1.8.5.6
Re: [PATCH 17/18] scsi: Add scsi_vpd_tpg_id()
Quoted 84 lines · Hannes Reinecke
Implement
scsi_vpd_tpg_id()to extract the target
port group id and the relative port id from
SCSI VPD page0x83.Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/scsi_lib.c | 48
++++++++++++++++++++++++++++++++++++++++++++++
include/scsi/scsi_device.h | 1 +2 files changed, 49 insertions(+)drivers/scsi/scsi_lib.c +1
-0@@ -23,6 +23,7 @@ #include <linux/scatterlist.h> #include <linux/blk-mq.h> #include <linux/ratelimit.h> +#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>drivers/scsi/scsi_lib.c +47
-0@@ -3294,3 +3295,50 @@ next_desig: return id_size; } EXPORT_SYMBOL(scsi_vpd_lun_id); + +/* +* scsi_vpd_tpg_id - return a target port group identifier +* @sdev: SCSI device +* +* Returns the Target Port Group identifier from the information +* froom VPD page 0x83 of the device. +* +* Returns the identifier or error on failure. +*/ +int scsi_vpd_tpg_id (struct scsi_device *sdev,int *rel_id) +{ +unsigned char *d; +unsigned char __rcu *vpd_pg83; +int group_id = -EAGAIN , rel_port =-1 ; + +rcu_read_lock (); + vpd_pg83 =rcu_dereference (sdev->vpd_pg83); +if (!vpd_pg83) { +rcu_read_unlock (); +return -ENXIO ; + } + + d = sdev->vpd_pg83 +4 ; +while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) { +switch (d[1 ] &0xf ) { +case 0x4 : +/* Relative target port */ + rel_port =get_unaligned_be16 (&d[6 ]); +break ; +case 0x5 : +/* Target port group */ + group_id =get_unaligned_be16 (&d[6 ]); +break ; +default : +break ; + } + d += d[3 ] +4 ; + } +rcu_read_unlock (); + +if (group_id >=0 && rel_id && rel_port !=-1 ) + *rel_id = rel_port; + +return group_id; +} +EXPORT_SYMBOL (scsi_vpd_tpg_id);include/scsi/scsi_device.h +1
-0@@ -416,6 +416,7 @@ static inline int scsi_execute_req(structscsi_device *sdev, extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); +extern int scsi_vpd_tpg_id (struct scsi_device *,int *);
Quoted 3 lines
#ifdefCONFIG_PM
extern intscsi_autopm_get_device(struct scsi_device *);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 18/18 scsi_dh_alua: use scsi_vpd_tpg_id()
In reply to Hannes Reinecke--- drivers/scsi/device_handler/scsi_dh_alua.c | 39 +++++------------------------- 1 file changed, 6 insertions(+), 33 deletions(-)
drivers/scsi/device_handler/scsi_dh_alua.c +6 -33
@@ -320,38 +320,10 @@ static int alua_check_tpgs(struct scsi_device *sdev)*/ static int alua_check_vpd (struct scsi_device *sdev,struct alua_dh_data *h) { -unsigned char *d; -unsigned char __rcu *vpd_pg83; +int rel_port =-1 , group_id; -rcu_read_lock (); -if (!rcu_dereference (sdev->vpd_pg83)){ -rcu_read_unlock (); -return SCSI_DH_DEV_UNSUPP ; - } - -/* -* Look for the correct descriptor. -*/ - vpd_pg83 =rcu_dereference (sdev->vpd_pg83); - d = vpd_pg83 +4 ; -while (d < vpd_pg83 + sdev->vpd_pg83_len) { -switch (d[1 ] &0xf ) { -case 0x4 : -/* Relative target port */ - h->rel_port =get_unaligned_be16 (&d[6 ]); -break ; -case 0x5 : -/* Target port group */ - h->group_id =get_unaligned_be16 (&d[6 ]); -break ; -default : -break ; - } - d += d[3 ] +4 ; - } -rcu_read_unlock (); - -if (h->group_id ==-1 ) { + group_id =scsi_vpd_tpg_id (sdev, &rel_port); +if (group_id <0 ) {/* * Internal error; TPGS supported but required * VPD identification descriptors not present.
@@ -360,10 +332,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h)sdev_printk (KERN_INFO , sdev,"%s: No target port descriptors found\n" ,ALUA_DH_NAME ); - h->state =TPGS_STATE_OPTIMIZED ; - h->tpgs =TPGS_MODE_NONE ;return SCSI_DH_DEV_UNSUPP ; } + h->rel_port = rel_port; + h->group_id = group_id; +sdev_printk (KERN_INFO , sdev,"%s: port group %02x rel port %02x\n" ,ALUA_DH_NAME , h->group_id, h->rel_port);
Signature · 1 line
1.8.5.6
Re: [PATCH 18/18] scsi_dh_alua: use scsi_vpd_tpg_id()
Quoted 68 lines · Hannes Reinecke
Signed-off-by Hannes Reinecke <[email protected]>---
drivers/scsi/device_handler/scsi_dh_alua.c | 39 +++++---------------
----------1 file changed, 6 insertions(+), 33 deletions(-)drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -320,38 +320,10 @@ static int alua_check_tpgs(struct scsi_device*sdev) */ static int
alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h)
{drivers/scsi/device_handler/scsi_dh_alua.c +1
-2-unsigned char *d; -unsigned char __rcu *vpd_pg83; +int rel_port =-1 , group_id;drivers/scsi/device_handler/scsi_dh_alua.c +2
-29-rcu_read_lock (); -if (!rcu_dereference (sdev->vpd_pg83)){ -rcu_read_unlock (); -return SCSI_DH_DEV_UNSUPP ; - } - -/* -* Look for the correct descriptor. -*/ - vpd_pg83 =rcu_dereference (sdev->vpd_pg83); - d = vpd_pg83 +4 ; -while (d < vpd_pg83 + sdev->vpd_pg83_len) { -switch (d[1 ] &0xf ) { -case 0x4 : -/* Relative target port */ - h->rel_port =get_unaligned_be16 (&d[6 ]); -break ; -case 0x5 : -/* Target port group */ - h->group_id =get_unaligned_be16 (&d[6 ]); -break ; -default : -break ; - } - d += d[3 ] +4 ; - } -rcu_read_unlock (); - -if (h->group_id ==-1 ) { + group_id =scsi_vpd_tpg_id (sdev, &rel_port); +if (group_id <0 ) {/*
* Internal error; TPGS supported but required
* VPD identification descriptors not present.drivers/scsi/device_handler/scsi_dh_alua.c +0
-0@@ -360,10 +332,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h) sdev_printk(KERN_INFO, sdev,"%s: No target port descriptors found\n",
ALUA_DH_NAME);drivers/scsi/device_handler/scsi_dh_alua.c +0
-2- h->state =TPGS_STATE_OPTIMIZED ; - h->tpgs =TPGS_MODE_NONE ;return
SCSI_DH_DEV_UNSUPP;
}drivers/scsi/device_handler/scsi_dh_alua.c +3
-0+ h->rel_port = rel_port; + h->group_id = group_id; +
Quoted 3 lines
sdev_printk(KERN_INFO, sdev,
"%s: port group %02x rel port %02x\n",ALUA_DH_NAME,h->group_id,h->rel_port);
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Can you push out a git branch with this code for easier review as well?
Hannes Reinecke
AppliedQuoted 2 lines · Christoph Hellwig
Can you push out a git branch with this code for easier review as well?
Pushed to kernel.org:hare/scsi-devel.git branch alua.v6 Branch is based upon mkp/scsi.git branch 4.5/scsi-queue
Thanks for reviewing.
Cheers,
Hannes
Signature · 9 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 9 lines · Hannes Reinecke
Hi all,
here's the first part of my ALUA device handler update. It's mainly bugfixes and minor improvements; the two important things are the addition of VPD parsing functions
scsi_vpd_lun_id()andscsi_vpd_tpg_id().
This series has been split off from the original 'Asynchronous ALUA' patchset, as these bits are pretty uncontroversial and have a good chance of being merged reasonably soon.
I've already reviewed most patches, but the other ones looks fine as well:
Let's get this into the 4.5 queue ASAP an then tackle the actually interesting bits next!
Quoted 11 lines · Christoph Hellwig
Quoted 9 lines · Hannes Reinecke
Hi all,
here's the first part of my ALUA device handler update. It's mainly bugfixes and minor improvements; the two important things are the addition of VPD parsing functions
scsi_vpd_lun_id()andscsi_vpd_tpg_id().
This series has been split off from the original 'Asynchronous ALUA' patchset, as these bits are pretty uncontroversial and have a good chance of being merged reasonably soon.
Quoted 8 lines
I've already reviewed most patches, but the other ones looks fine as well:
Reviewed-by Christoph Hellwig <[email protected]>Let's get this into the 4.5 queue ASAP an then tackle the actually interesting bits next!
I'm all for it.
One thing, though: I don't really agree with Barts objection that moving to a workqueue would tie in too many resources. Thing is, I'm not convinces that using a work queue is allocating too many resources (we're speaking of 460 vs 240 bytes here). Also we have to retry commands for quite some time (cite the infamous NetApp takeover/giveback, which can take minutes). If we were to handle that without workqueue we'd have to initiate the retry from the end_io callback, causing a quite deep stack recursion. Which I'm not really fond of.
But if anyone has a better idea on how to handle retries without the need for workqueues I'm all ears :-)
Cheers,
Hannes
Signature · 9 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 10 lines · Hannes Reinecke
One thing, though: I don't really agree with Barts objection that moving to a workqueue would tie in too many resources. Thing is, I'm not convinces that using a work queue is allocating too many resources (we're speaking of 460 vs 240 bytes here). Also we have to retry commands for quite some time (cite the infamous NetApp takeover/giveback, which can take minutes). If we were to handle that without workqueue we'd have to initiate the retry from the
end_iocallback, causing a quite deep stack recursion. Which I'm not really fond of.
Quoted 2 lines
But if anyone has a better idea on how to handle retries without the need for workqueues I'm all ears :-)
I tend to agree with you, but you better warm up that discussion again on the old thread that actually has Bart on Cc. Or just resend once Martin has merged this patch, and have discussion around that version.
Quoted 11 lines · Christoph Hellwig
Quoted 10 lines · Hannes Reinecke
One thing, though: I don't really agree with Barts objection that moving to a workqueue would tie in too many resources. Thing is, I'm not convinces that using a work queue is allocating too many resources (we're speaking of 460 vs 240 bytes here). Also we have to retry commands for quite some time (cite the infamous NetApp takeover/giveback, which can take minutes). If we were to handle that without workqueue we'd have to initiate the retry from the
end_iocallback, causing a quite deep stack recursion. Which I'm not really fond of.
Quoted 7 lines
Quoted 2 lines
But if anyone has a better idea on how to handle retries without the need for workqueues I'm all ears :-)
I tend to agree with you, but you better warm up that discussion again on the old thread that actually has Bart on Cc. Or just resend once Martin has merged this patch, and have discussion around that version.
Fully agree. So I'm waiting for Martin to pick up the patches first.
Cheers,
Hannes
Signature · 9 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 9 lines · Hannes Reinecke
One thing, though: I don't really agree with Barts objection that moving to a workqueue would tie in too many resources. Thing is, I'm not convinces that using a work queue is allocating too many resources (we're speaking of 460 vs 240 bytes here). Also we have to retry commands for quite some time (cite the infamous NetApp takeover/giveback, which can take minutes). If we were to handle that without workqueue we'd have to initiate the retry from the
end_iocallback, causing a quite deep stack recursion. Which I'm not really fond of.
Hello Hannes,
Sorry if I wasn't clear enough in my previous e-mail about this topic but I'm more concerned about the additional memory needed for thread stacks and thread control data structures than about the additional memory needed for the workqueue. I'd like to see the ALUA device handler implementation scale to thousands of LUNs and target port groups. In case all connections between an initiator and a target port group fail, with a synchronous implementation of STPG we will either need a large number of threads (in case of one thread per STPG command) or the STPG commands will be serialized (if there are fewer threads than portal groups). Neither alternative looks attractive to me.
BTW, not all storage arrays need STPG retries. Some arrays are able to process an STPG command quickly (this means within a few seconds).
A previous discussion about this topic is available e.g. at http://thread.gmane.org/gmane.linux.scsi/105340/focus=105601.
Bart.
Quoted 25 lines · Bart Van Assche
Quoted 9 lines · Hannes Reinecke
One thing, though: I don't really agree with Barts objection that moving to a workqueue would tie in too many resources. Thing is, I'm not convinces that using a work queue is allocating too many resources (we're speaking of 460 vs 240 bytes here). Also we have to retry commands for quite some time (cite the infamous NetApp takeover/giveback, which can take minutes). If we were to handle that without workqueue we'd have to initiate the retry from the
end_iocallback, causing a quite deep stack recursion. Which I'm not really fond of.Hello Hannes,
Sorry if I wasn't clear enough in my previous e-mail about this topic but I'm more concerned about the additional memory needed for thread stacks and thread control data structures than about the additional memory needed for the workqueue. I'd like to see the ALUA device handler implementation scale to thousands of LUNs and target port groups. In case all connections between an initiator and a target port group fail, with a synchronous implementation of STPG we will either need a large number of threads (in case of one thread per STPG command) or the STPG commands will be serialized (if there are fewer threads than portal groups). Neither alternative looks attractive to me.
Quoted 6 lines
BTW, not all storage arrays need STPG retries. Some arrays are able to process an STPG command quickly (this means within a few seconds).
A previous discussion about this topic is available e.g. at
http://thread.gmane.org/gmane.linux.scsi/105340/focus=105601.
Well, one could argue that the whole point of this patchset is to allow you to serialize STPGs :-)
We definitely need to serialize STPGs for the same target port group; the current implementation is far too limited to take that into account.
But the main problem I'm facing with the current implementation is that we cannot handle retries. An RTPG or an STPG might fail, at which point we need to re-run RTPG to figure out the current status. (We also need to send RTPGs when we receive an "ALUA state changed"
UA, but that's slightly beside the point).
The retry cannot be send directly, as we're evaluating the status from end_io context. So to instantiate a retry we need to move it over to a workqueue.
Or, at least, that's the solution I'm able to come up with. If you have other ideas it'd be most welcome.
Cheers,
Hannes
Signature · 9 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 48 lines · Hannes Reinecke
Quoted 25 lines · Bart Van Assche
Quoted 9 lines · Hannes Reinecke
One thing, though: I don't really agree with Barts objection that moving to a workqueue would tie in too many resources. Thing is, I'm not convinces that using a work queue is allocating too many resources (we're speaking of 460 vs 240 bytes here). Also we have to retry commands for quite some time (cite the infamous NetApp takeover/giveback, which can take minutes). If we were to handle that without workqueue we'd have to initiate the retry from the
end_iocallback, causing a quite deep stack recursion. Which I'm not really fond of.Hello Hannes,
Sorry if I wasn't clear enough in my previous e-mail about this topic but I'm more concerned about the additional memory needed for thread stacks and thread control data structures than about the additional memory needed for the workqueue. I'd like to see the ALUA device handler implementation scale to thousands of LUNs and target port groups. In case all connections between an initiator and a target port group fail, with a synchronous implementation of STPG we will either need a large number of threads (in case of one thread per STPG command) or the STPG commands will be serialized (if there are fewer threads than portal groups). Neither alternative looks attractive to me.
Quoted 6 lines
BTW, not all storage arrays need STPG retries. Some arrays are able to process an STPG command quickly (this means within a few seconds).
A previous discussion about this topic is available e.g. at
http://thread.gmane.org/gmane.linux.scsi/105340/focus=105601.Well, one could argue that the whole point of this patchset is to allow you to serialize STPGs :-)
We definitely need to serialize STPGs for the same target port group; the current implementation is far too limited to take that into account.
But the main problem I'm facing with the current implementation is that we cannot handle retries. An RTPG or an STPG might fail, at which point we need to re-run RTPG to figure out the current status. (We also need to send RTPGs when we receive an "ALUA state changed"
UA, but that's slightly beside the point).
The retry cannot be send directly, as we're evaluating the status fromend_iocontext. So to instantiate a retry we need to move it over to a workqueue.
Quoted 2 lines
Or, at least, that's the solution I'm able to come up with. If you have other ideas it'd be most welcome.
Hello Hannes,
I agree that retries have to be handled from workqueue context instead of end_io context. But in workqueue context we can choose whether to submit the retry synchronously or asynchronously. Unless I overlooked something I don't see why the retry should be submitted synchronously.
Bart.
Quoted 4 lines · Bart Van Assche
Quoted 1 line · Hannes Reinecke
On 11/20/2015 11:58 PM, Bart Van Assche wrote:
[ .. ]
Quoted 26 lines
Quoted 23 lines
Quoted 7 lines
BTW, not all storage arrays need STPG retries. Some arrays are able to process an STPG command quickly (this means within a few seconds).
A previous discussion about this topic is available e.g. at
http://thread.gmane.org/gmane.linux.scsi/105340/focus=105601.Well, one could argue that the whole point of this patchset is to allow you to serialize STPGs :-)
We definitely need to serialize STPGs for the same target port group; the current implementation is far too limited to take that into account.
But the main problem I'm facing with the current implementation is that we cannot handle retries. An RTPG or an STPG might fail, at which point we need to re-run RTPG to figure out the current status. (We also need to send RTPGs when we receive an "ALUA state changed"
UA, but that's slightly beside the point).
The retry cannot be send directly, as we're evaluating the status fromend_iocontext. So to instantiate a retry we need to move it over to a workqueue.Quoted 2 lines
Or, at least, that's the solution I'm able to come up with. If you have other ideas it'd be most welcome.
Quoted 8 lines
Hello Hannes,
I agree that retries have to be handled from workqueue context instead of
end_iocontext. But in workqueue context we can choose whether to submit the retry synchronously or asynchronously. Unless I overlooked something I don't see why the retry should be submitted synchronously.
Good point. Sure we can do this; the primary difference would be whether the workqueue is ordered or not.
An unordered workqueue would be resulting in not serializing retries, hence achieving pretty much what you asked.
Cheers,
Hannes
Signature · 9 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html