Re: [PATCH 8/8] hptiop: fix calls to dma_set_mask()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask() incorrectly made a second call with the
32 bit DMA mask value when the call with the 64 bit DMA mask value succeeded.

Fixes: 453cd3700ca3 ("scsi: hptiop: use dma_set_mask")
Cc: 
Suggested-by: Ewan D. Milne 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/hptiop.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 3eedfd4f8f57..251c084a6ff0 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1292,6 +1292,7 @@ static int hptiop_probe(struct pci_dev *pcidev, const 
struct pci_device_id *id)
dma_addr_t start_phy;
void *start_virt;
u32 offset, i, req_size;
+   int rc;
 
dprintk("hptiop_probe(%p)\n", pcidev);
 
@@ -1308,9 +1309,12 @@ static int hptiop_probe(struct pci_dev *pcidev, const 
struct pci_device_id *id)
 
/* Enable 64bit DMA if possible */
iop_ops = (struct hptiop_adapter_ops *)id->driver_data;
-   if (dma_set_mask(&pcidev->dev,
-DMA_BIT_MASK(iop_ops->hw_dma_bit_mask)) ||
-   dma_set_mask(&pcidev->dev, DMA_BIT_MASK(32))) {
+   rc = dma_set_mask(&pcidev->dev,
+ DMA_BIT_MASK(iop_ops->hw_dma_bit_mask));
+   if (rc)
+   rc = dma_set_mask(&pcidev->dev, DMA_BIT_MASK(32));
+
+   if (rc) {
printk(KERN_ERR "hptiop: fail to set dma_mask\n");
goto disable_pci_device;
}
-- 
2.16.4

Reviewed-by: Ewan D. Milne 



Re: [PATCH 7/8] hisi_sas: fix calls to dma_set_mask_and_coherent()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask_and_coherent() incorrectly made a second
call with the 32 bit DMA mask value when the call with the 64 bit DMA
mask value succeeded.  This resulted in FC connections failing due
to corrupted data buffers, and various other SCSI/FCP I/O errors.

Fixes: e4db40e7a1a2 ("scsi: hisi_sas: use dma_set_mask_and_coherent")
Cc: 
Suggested-by: Ewan D. Milne 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 8 ++--
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 +---
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c 
b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 923296653ed7..13ca5a0bdf6b 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -2484,6 +2484,7 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct 
platform_device *pdev,
struct Scsi_Host *shost;
struct hisi_hba *hisi_hba;
struct device *dev = &pdev->dev;
+   int error;
 
shost = scsi_host_alloc(hw->sht, sizeof(*hisi_hba));
if (!shost) {
@@ -2504,8 +2505,11 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct 
platform_device *pdev,
if (hisi_sas_get_fw_info(hisi_hba) < 0)
goto err_out;
 
-   if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) &&
-   dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
+   error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+   if (error)
+   error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+
+   if (error) {
dev_err(dev, "No usable DMA addressing method\n");
goto err_out;
}
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 00738d0673fe..79390f235c7e 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -2742,10 +2742,12 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
if (rc)
goto err_out_disable_device;
 
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+   rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (rc)
+   rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+   if (rc) {
dev_err(dev, "No usable DMA addressing method\n");
-   rc = -EIO;
+   rc = -ENODEV;
goto err_out_regions;
}
 
-- 
2.16.4

Can we remove the last sentence "This resulted in...", Martin?

Reviewed-by: Ewan D. Milne 


Re: [PATCH 6/8] csiostor: fix calls to dma_set_mask_and_coherent()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask_and_coherent() incorrectly made a second
call with the 32 bit DMA mask value when the call with the 64 bit DMA
mask value succeeded.

Fixes: c22b332d811b ("scsi: csiostor: switch to generic DMA API")
Cc: 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/csiostor/csio_init.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/csiostor/csio_init.c 
b/drivers/scsi/csiostor/csio_init.c
index 460e4ee1c8fe..a6dd704d7f2d 100644
--- a/drivers/scsi/csiostor/csio_init.c
+++ b/drivers/scsi/csiostor/csio_init.c
@@ -206,8 +206,11 @@ csio_pci_init(struct pci_dev *pdev, int *bars)
pci_set_master(pdev);
pci_try_set_mwi(pdev);
 
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+   rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (rv)
+   rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+   if (rv) {
+   rv = -ENODEV;
dev_err(&pdev->dev, "No suitable DMA available.\n");
goto err_release_regions;
}
-- 
2.16.4

Reviewed-by: Ewan D. Milne 


Re: [PATCH 5/8] bfa: fix calls to dma_set_mask_and_coherent()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask_and_coherent() incorrectly made a second
call with the 32 bit DMA mask value when the call with the 64 bit DMA
mask value succeeded.  This resulted in FC connections failing due
to corrupted data buffers, and various other SCSI/FCP I/O errors.

Fixes: a69b080025ea ("scsi: bfa: use dma_set_mask_and_coherent")
Cc: 
Suggested-by: Ewan D. Milne 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/bfa/bfad.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 42a0caf6740d..0a66a189 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -727,7 +727,7 @@ bfad_init_timer(struct bfad_s *bfad)
 int
 bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
 {
-   int rc = -ENODEV;
+   int rc = -ENODEV;
 
if (pci_enable_device(pdev)) {
printk(KERN_ERR "pci_enable_device fail %p\n", pdev);
@@ -739,8 +739,12 @@ bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
 
pci_set_master(pdev);
 
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+   rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (rc)
+   rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+
+   if (rc) {
+   rc = -ENODEV;
printk(KERN_ERR "dma_set_mask_and_coherent fail %p\n", pdev);
goto out_release_region;
}
@@ -1534,6 +1538,7 @@ bfad_pci_slot_reset(struct pci_dev *pdev)
 {
struct bfad_s *bfad = pci_get_drvdata(pdev);
u8 byte;
+   int rc;
 
dev_printk(KERN_ERR, &pdev->dev,
   "bfad_pci_slot_reset flags: 0x%x\n", bfad->bfad_flags);
@@ -1561,8 +1566,11 @@ bfad_pci_slot_reset(struct pci_dev *pdev)
pci_save_state(pdev);
pci_set_master(pdev);
 
-   if (dma_set_mask_and_coherent(&bfad->pcidev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&bfad->pcidev->dev, DMA_BIT_MASK(32)))
+   rc = dma_set_mask_and_coherent(&bfad->pcidev->dev, DMA_BIT_MASK(64));
+   if (rc)
+   rc = dma_set_mask_and_coherent(&bfad->pcidev->dev,
+  DMA_BIT_MASK(32));
+   if (rc)
goto out_disable_device;
 
if (restart_bfa(bfad) == -1)
-- 
2.16.4

Can we remove the last sentence "This resulted in...", Martin?

Reviewed-by: Ewan D. Milne 



Re: [PATCH 4/8] 3w-sas: fix calls to dma_set_mask_and_coherent()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask_and_coherent() incorrectly made a second
call with the 32 bit DMA mask value when the call with the 64 bit DMA
mask value succeeded.

Fixes: 3a21986f1a59 ("scsi: aic94xx: fully convert to the generic DMA API")
Cc: 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/aic94xx/aic94xx_init.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/aic94xx/aic94xx_init.c 
b/drivers/scsi/aic94xx/aic94xx_init.c
index f83f79b07b50..d41f645e8454 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -769,9 +769,11 @@ static int asd_pci_probe(struct pci_dev *dev, const struct 
pci_device_id *id)
if (err)
goto Err_remove;
 
-   err = -ENODEV;
-   if (dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32))) {
+   err = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(64));
+   if (err)
+   err = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
+   if (err) {
+   err = -ENODEV;
asd_printk("no suitable DMA mask for %s\n", pci_name(dev));
goto Err_remove;
}
-- 
2.16.4

The patch subject should be "aic94xx:", Martin, can you fix this up?

Reviewed-by: Ewan D. Milne 


Re: [PATCH 3/8] 3w-sas: fix calls to dma_set_mask_and_coherent()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask_and_coherent() incorrectly made a second
call with the 32 bit DMA mask value when the call with the 64 bit DMA
mask value succeeded.

Fixes: b1fa122930c4 ("scsi: 3w-sas: fully convert to the generic DMA API")
Cc: 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/3w-sas.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index e8f5f7c63190..2d15b878bd94 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -1572,8 +1572,10 @@ static int twl_probe(struct pci_dev *pdev, const struct 
pci_device_id *dev_id)
pci_set_master(pdev);
pci_try_set_mwi(pdev);
 
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+   retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (retval)
+   retval = dma_set_mask_and_coherent(&pdev->dev, 
DMA_BIT_MASK(32));
+   if (retval) {
TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
retval = -ENODEV;
goto out_disable_device;
@@ -1804,8 +1806,10 @@ static int twl_resume(struct pci_dev *pdev)
pci_set_master(pdev);
pci_try_set_mwi(pdev);
 
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+   retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (retval)
+   retval = dma_set_mask_and_coherent(&pdev->dev, 
DMA_BIT_MASK(32));
+   if (retval) {
TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during 
resume");
retval = -ENODEV;
goto out_disable_device;
-- 
2.16.4

Reviewed-by: Ewan D. Milne 



Re: [PATCH 2/8] 3w-9xxx: fix calls to dma_set_mask_and_coherent()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask_and_coherent() incorrectly made a second
call with the 32 bit DMA mask value when the call with the 64 bit DMA
mask value succeeded.

Fixes: b000bced5739 ("scsi: 3w-9xxx: fully convert to the generic DMA API")
Cc: 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/3w-9xxx.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index a3c20e3a8b7c..3337b1e80412 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -2009,7 +2009,7 @@ static int twa_probe(struct pci_dev *pdev, const struct 
pci_device_id *dev_id)
struct Scsi_Host *host = NULL;
TW_Device_Extension *tw_dev;
unsigned long mem_addr, mem_len;
-   int retval = -ENODEV;
+   int retval;
 
retval = pci_enable_device(pdev);
if (retval) {
@@ -2020,8 +2020,10 @@ static int twa_probe(struct pci_dev *pdev, const struct 
pci_device_id *dev_id)
pci_set_master(pdev);
pci_try_set_mwi(pdev);
 
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+   retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (retval)
+   retval = dma_set_mask_and_coherent(&pdev->dev, 
DMA_BIT_MASK(32));
+   if (retval) {
TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
retval = -ENODEV;
goto out_disable_device;
@@ -2240,8 +2242,10 @@ static int twa_resume(struct pci_dev *pdev)
pci_set_master(pdev);
pci_try_set_mwi(pdev);
 
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
+   retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (retval)
+   retval = dma_set_mask_and_coherent(&pdev->dev, 
DMA_BIT_MASK(32));
+   if (retval) {
TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during 
resume");
retval = -ENODEV;
goto out_disable_device;
-- 
2.16.4

Reviewed-by: Ewan D. Milne 



Re: [PATCHv2 0/8] scsi: fixup dma_set_mask_and_coherent() calls

2019-02-25 Thread Ewan Milne


The recent patchset to use dma_set_mask_and_coherent() introduced
a regression where a call to set a 64-bit DMA mask was followed
by a call to set a 32-bit DMA mask, leading to I/O errors and
data corruption.

Patchset is based on a suggestions from Ewan Milne.

Hannes Reinecke (8):
  lpfc: fix calls to dma_set_mask_and_coherent()
  3w-9xxx: fix calls to dma_set_mask_and_coherent()
  3w-sas: fix calls to dma_set_mask_and_coherent()
  3w-sas: fix calls to dma_set_mask_and_coherent()
  bfa: fix calls to dma_set_mask_and_coherent()
  csiostor: fix calls to dma_set_mask_and_coherent()
  hisi_sas: fix calls to dma_set_mask_and_coherent()
  hptiop: fix calls to dma_set_mask()

 drivers/scsi/3w-9xxx.c | 14 +-
 drivers/scsi/3w-sas.c  | 12 
 drivers/scsi/aic94xx/aic94xx_init.c|  8 +---
 drivers/scsi/bfa/bfad.c| 18 +-
 drivers/scsi/csiostor/csio_init.c  |  7 +--
 drivers/scsi/hisi_sas/hisi_sas_main.c  |  8 ++--
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c |  8 +---
 drivers/scsi/hptiop.c  | 10 +++---
 drivers/scsi/lpfc/lpfc_init.c  | 19 ---
 9 files changed, 70 insertions(+), 34 deletions(-)

-- 
2.16.4



The code changes look fine, I only have 3 commit-msg related comments:

 4/8 - Subject line should read "aic94xx:" not "3w-sas:" (from 3/8?)
 5/8 - Remove last sentence from patch description
 7/8 - Remove last sentence from patch description

(The only errors I actually encountered were with the lpfc driver.)

Martin, can you fix this up in patchwork?  I'll add Reviewed-by: each.

-Ewan


Re: [PATCH 1/8] lpfc: fix calls to dma_set_mask_and_coherent()

2019-02-25 Thread Ewan Milne
The change to use dma_set_mask_and_coherent() incorrectly made a second
call with the 32 bit DMA mask value when the call with the 64 bit DMA
mask value succeeded.  This resulted in NVMe/FC connections failing due
to corrupted data buffers, and various other SCSI/FCP I/O errors.

Fixes: f30e1bfd6154 ("scsi: lpfc: use dma_set_mask_and_coherent")
Cc: 
Suggested-by: Don Dutile 
Signed-off-by: Ewan D. Milne 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/lpfc/lpfc_init.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index eef6b929c327..59b098cb5787 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7693,15 +7693,18 @@ lpfc_sli_pci_mem_setup(struct lpfc_hba *phba)
unsigned long bar0map_len, bar2map_len;
int i, hbq_count;
void *ptr;
-   int error = -ENODEV;
+   int error;
 
if (!pdev)
-   return error;
+   return -ENODEV;
 
/* Set the device DMA mask size */
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
+   error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (error)
+   error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+   if (error)
return error;
+   error = -ENODEV;
 
/* Get the bus address of Bar0 and Bar2 and the number of bytes
 * required by each mapping.
@@ -10053,11 +10056,13 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
uint32_t if_type;
 
if (!pdev)
-   return error;
+   return -ENODEV;
 
/* Set the device DMA mask size */
-   if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
-   dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
+   error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+   if (error)
+   error = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+   if (error)
return error;
 
/*
-- 
2.16.4

Reviewed-by: Ewan D. Milne 


Re: [PATCH] scsi_error: Remove scsi_block_when_processing_errors: message

2018-10-17 Thread Ewan Milne
- Original Message -
From: "Laurence Oberman" 
To: "linux-scsi" 
Cc: "Hannes Reinecke" , "Ewan Milne" , "Bart 
Van Assche" , "James Bottomley" 

Sent: Tuesday, October 16, 2018 4:39:16 PM
Subject: [PATCH] scsi_error: Remove scsi_block_when_processing_errors: message

This message floods the log when enabling mask 0x7 for
 /proc/sys/dev/scsi/logging_level 
  kernel: scsi_block_when_processing_errors: rtn: 1 
Its not needed and makes tracing just scsi_eh* messages way too verbose
so get rid of it

Signed-off-by: Laurence Oberman 

---
 drivers/scsi/scsi_error.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index b7a8fdf..c736d61 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -338,9 +338,6 @@ int scsi_block_when_processing_errors(struct
scsi_device *sdev)
 
    online = scsi_device_online(sdev);
 
-   SCSI_LOG_ERROR_RECOVERY(5, sdev_printk(KERN_INFO, sdev,
-   "%s: rtn: %d\n", __func__, online));
-
    return online;
 }
 EXPORT_SYMBOL(scsi_block_when_processing_errors);
-- 
1.8.3.1

Yes, agreed.

Reviewed-by: Ewan D. Milne 


Re: SG does not ignore dxferp (direct io + mmap)

2016-11-25 Thread Ewan Milne
>> ---
>> 
>> In other words, this commit made the bad behavior go away in 4.8.
>> Need to look at this in more detail, it doesn't appear as if this patch
>> was intended to fix such a problem.
>> 
>> -Ewan
>
>Are you sure it did? I can repropduce copy_to_user() errors with 4.8 as well.
>Using the very same reproducer. On 4.8 it's just harder to trigger and
>doesn't trigger on AHCI as fas as I can telli (maybe I just haven't hit
>it hard enough). I can trigger it on QEMUs SCSI CDROM emulation and hpsa
>though. I cannot however trigger this with a minimal config inside an initrd.

It did for Eyal's supplied test case on my machine, but that was not an
exhaustive test, and I am a little suspicious that the behavior change was
due to a side-effect of the patch rather than actually fixing something.

I think what we need to understand is what caused the regression in the
first place, I probably should have been bisecting the original failure
rather than trying to find where it started working.

I was running against an internal (physical) drive.

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


Re: [PATCH] libfc: unsafe refcounting in fc_rport_work()

2016-04-20 Thread Ewan Milne

- Original Message -
From: James Bottomley 
To: Hannes Reinecke , Martin K. Petersen 

Cc: Christoph Hellwig , Ewan Milne , 
linux-scsi@vger.kernel.org
Sent: Wed, 20 Apr 2016 15:03:12 -0400 (EDT)
Subject: Re: [PATCH] libfc: unsafe refcounting in fc_rport_work()

On Wed, 2016-04-20 at 15:24 +0200, Hannes Reinecke wrote:
> When pushing items on a workqueue we cannot take reference
> when the workqueue item is executed, as the structure might
> already been freed at that time.
> So instead we need to take a reference before adding it
> to the workqueue, thereby ensuring that the workqueue item
> will always be valid.

>Have you actually seen this happen?  The rdata structure is fully ref
>counted, so if it's done a final put, then something should see
>unreferenced memory.  It looks like the model is that the final put is
>done from the queue, so I don't quite see how you can lose the final
>reference in either of the places you alter.

I have two dumps with freed rport structures that have delayed_work
items that are still on the active timer list.  Both are with FCoE, one
using bnx and the other using ixgbe.  Something is wrong.  I'm not
sure why we don't see anything on regular FC.

It seems to me that we should be holding a kref on the rport while
a work item is pending, but I'm not sure releasing it at the end of the
work function is OK, either.  The workqueue code might still reference
the embedded work or delayed_work on the way out, no?

I agree with Christoph, this whole thing needs looking at.  All the
delayed_work stuff seems problematic to me.  James S fixed a 3-way
deadlock involving this code a while back, for instance.

-Ewan


> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/libfc/fc_rport.c | 25 +++--
>  1 file changed, 19 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/scsi/libfc/fc_rport.c
> b/drivers/scsi/libfc/fc_rport.c
> index 589ff9a..8b08263f 100644
> --- a/drivers/scsi/libfc/fc_rport.c
> +++ b/drivers/scsi/libfc/fc_rport.c
> @@ -263,7 +263,6 @@ static void fc_rport_work(struct work_struct
> *work)
>   ids = rdata->ids;
>   rdata->event = RPORT_EV_NONE;
>   rdata->major_retries = 0;
> - kref_get(&rdata->kref);
>   mutex_unlock(&rdata->rp_mutex);
>  
>   if (!rport)
> @@ -297,7 +296,6 @@ static void fc_rport_work(struct work_struct
> *work)
>   FC_RPORT_DBG(rdata, "lld callback ev %d\n",
> event);
>   rdata->lld_event_callback(lport, rdata,
> event);
>   }
> - kref_put(&rdata->kref, lport->tt.rport_destroy);
>   break;
>  
>   case RPORT_EV_FAILED:
> @@ -377,6 +375,7 @@ static void fc_rport_work(struct work_struct
> *work)
>   mutex_unlock(&rdata->rp_mutex);
>   break;
>   }
> + kref_put(&rdata->kref, lport->tt.rport_destroy);
>  }
>  
>  /**
> @@ -438,8 +437,15 @@ static void fc_rport_enter_delete(struct
> fc_rport_priv *rdata,
>  
>   fc_rport_state_enter(rdata, RPORT_ST_DELETE);
>  
> - if (rdata->event == RPORT_EV_NONE)
> - queue_work(rport_event_queue, &rdata->event_work);
> + if (rdata->event == RPORT_EV_NONE) {
> + if (!kref_get_unless_zero(&rdata->kref)) {
> + FC_RPORT_DBG(rdata, "port already
> deleted\n");
> + return;
> + }
> + if (!queue_work(rport_event_queue, &rdata
> ->event_work))
> + kref_put(&rdata->kref,
> +  rdata->local_port
> ->tt.rport_destroy);
> + }
>   rdata->event = event;
>  }
>  
> @@ -487,8 +493,15 @@ static void fc_rport_enter_ready(struct
> fc_rport_priv *rdata)
>  
>   FC_RPORT_DBG(rdata, "Port is Ready\n");
>  
> - if (rdata->event == RPORT_EV_NONE)
> - queue_work(rport_event_queue, &rdata->event_work);
> + if (rdata->event == RPORT_EV_NONE) {
> + if (!kref_get_unless_zero(&rdata->kref)) {
> + FC_RPORT_DBG(rdata, "port already
> deleted\n");
> + return;
> + }
> + if (!queue_work(rport_event_queue, &rdata
> ->event_work))
> + kref_put(&rdata->kref,
> +  rdata->local_port
> ->tt.rport_destroy);
> + }
>   rdata->event = RPORT_EV_READY;
>  }
>  


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


Re: [PATCH 5/5] Leftshift returned scsi_cmnd error code 16 bits

2016-03-14 Thread Ewan Milne
On Mon, 2016-03-14 at 11:14 -0700, Satish Kharat wrote:
> The the scsi_cmnd error code is expected to be in the left 16 bits
> of the result field. Change is to correct this.
> 
> Signed-off-by: Satish Kharat 
> ---
>  drivers/scsi/fnic/fnic.h  | 2 +-
>  drivers/scsi/fnic/fnic_scsi.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
> index 35264c7..e4e22f1 100644
> --- a/drivers/scsi/fnic/fnic.h
> +++ b/drivers/scsi/fnic/fnic.h
> @@ -39,7 +39,7 @@
>  
>  #define DRV_NAME "fnic"
>  #define DRV_DESCRIPTION  "Cisco FCoE HBA Driver"
> -#define DRV_VERSION  "1.6.0.22"
> +#define DRV_VERSION  "1.6.0.24"
>  #define PFX  DRV_NAME ": "
>  #define DFX DRV_NAME "%d: "
>  
> diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
> index 8492143..92a4ca3 100644
> --- a/drivers/scsi/fnic/fnic_scsi.c
> +++ b/drivers/scsi/fnic/fnic_scsi.c
> @@ -461,7 +461,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, 
> void (*done)(struct scsi_
>   FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
>   "returning DID_NO_CONNECT for IO as rport is 
> removed\n");
>   atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
> - sc->result = DID_NO_CONNECT;
> + sc->result = DID_NO_CONNECT<<16;
>   done(sc);
>   return 0;
>   }

Should just fix patch 3/5 instead.

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 4/5] Setting scsi host template to indicate that fnic does not support multiqueue

2016-03-14 Thread Ewan Milne
On Mon, 2016-03-14 at 11:14 -0700, Satish Kharat wrote:
> Fnic does not support mutiqueue. Setting the scsi_host_template in
> fnic_host_template to indicate that.
> 
> Changing fnic_version from 1.6.0.21 to 1.6.0.22
> 
> Signed-off-by: Satish Kharat 
> ---
>  drivers/scsi/fnic/fnic.h  | 2 +-
>  drivers/scsi/fnic/fnic_main.c | 1 +
>  2 files changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
> index 9ddc920..35264c7 100644
> --- a/drivers/scsi/fnic/fnic.h
> +++ b/drivers/scsi/fnic/fnic.h
> @@ -39,7 +39,7 @@
>  
>  #define DRV_NAME "fnic"
>  #define DRV_DESCRIPTION  "Cisco FCoE HBA Driver"
> -#define DRV_VERSION  "1.6.0.21"
> +#define DRV_VERSION  "1.6.0.22"
>  #define PFX  DRV_NAME ": "
>  #define DFX DRV_NAME "%d: "
>  
> diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
> index 58ce902..fa8a121 100644
> --- a/drivers/scsi/fnic/fnic_main.c
> +++ b/drivers/scsi/fnic/fnic_main.c
> @@ -119,6 +119,7 @@ static struct scsi_host_template fnic_host_template = {
>   .max_sectors = 0x,
>   .shost_attrs = fnic_attrs,
>   .track_queue_depth = 1,
> + .disable_blk_mq = 1,
>  };
>  
>  static void

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 3/5] Using rport->dd_data to check rport online instead of rport_lookup.

2016-03-14 Thread Ewan Milne
On Mon, 2016-03-14 at 11:14 -0700, Satish Kharat wrote:
> When issuing I/O we check if rport is online through libfc
> rport_lookup() function which needs to be protected by mutex lock
> that cannot acquired in I/O context. The change is to use midlayer
> remote port’s dd_data which is preserved until its devloss timeout
> and no protection is required.
> 
> Fnic driver version changed from 1.6.0.20 to 1.6.0.21
> 
> Signed-off-by: Satish Kharat 
> ---
>  drivers/scsi/fnic/fnic.h  |  2 +-
>  drivers/scsi/fnic/fnic_scsi.c | 20 +++-
>  2 files changed, 12 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
> index 1023eae..9ddc920 100644
> --- a/drivers/scsi/fnic/fnic.h
> +++ b/drivers/scsi/fnic/fnic.h
> @@ -39,7 +39,7 @@
>  
>  #define DRV_NAME "fnic"
>  #define DRV_DESCRIPTION  "Cisco FCoE HBA Driver"
> -#define DRV_VERSION  "1.6.0.20"
> +#define DRV_VERSION  "1.6.0.21"
>  #define PFX  DRV_NAME ": "
>  #define DFX DRV_NAME "%d: "
>  
> diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
> index a3e0f69..8492143 100644
> --- a/drivers/scsi/fnic/fnic_scsi.c
> +++ b/drivers/scsi/fnic/fnic_scsi.c
> @@ -439,7 +439,6 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, 
> void (*done)(struct scsi_
>   int sg_count = 0;
>   unsigned long flags = 0;
>   unsigned long ptr;
> - struct fc_rport_priv *rdata;
>   spinlock_t *io_lock = NULL;
>   int io_lock_acquired = 0;
>  
> @@ -455,14 +454,17 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, 
> void (*done)(struct scsi_
>   return 0;
>   }
>  
> - rdata = lp->tt.rport_lookup(lp, rport->port_id);
> - if (!rdata || (rdata->rp_state == RPORT_ST_DELETE)) {
> - FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
> - "returning IO as rport is removed\n");
> - atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
> - sc->result = DID_NO_CONNECT;

You fixed this in patch 5/5 to << 16, might as well just do it right
in the first patch here and eliminate that one.

> - done(sc);
> - return 0;
> + if (rport) {
> + struct fc_rport_libfc_priv *rp = rport->dd_data;
> +
> + if (!rp || rp->rp_state != RPORT_ST_READY) {
> + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
> + "returning DID_NO_CONNECT for IO as rport is 
> removed\n");
> + atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
> + sc->result = DID_NO_CONNECT;
> + done(sc);
> + return 0;
> + }
>   }
>  
>   if (lp->state != LPORT_ST_READY || !(lp->link_up))

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 2/5] Cleanup the I/O that has timed out and is used to issue LUN reset

2016-03-14 Thread Ewan Milne
On Mon, 2016-03-14 at 11:14 -0700, Satish Kharat wrote:
> In case of LUN reset, the device reset command is issued with one of
> the I/Os that has timed out on that LUN. The change is to also return
> this I/O with error status set to DID_RESET.
> Fnic driver version changed from 1.6.0.19 to 1.6.0.20
> 
> Signed-off-by: Satish Kharat 
> ---
>  drivers/scsi/fnic/fnic.h  |  2 +-
>  drivers/scsi/fnic/fnic_scsi.c | 35 +++
>  2 files changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
> index 52a53f8..1023eae 100644
> --- a/drivers/scsi/fnic/fnic.h
> +++ b/drivers/scsi/fnic/fnic.h
> @@ -39,7 +39,7 @@
>  
>  #define DRV_NAME "fnic"
>  #define DRV_DESCRIPTION  "Cisco FCoE HBA Driver"
> -#define DRV_VERSION  "1.6.0.19"
> +#define DRV_VERSION  "1.6.0.20"
>  #define PFX  DRV_NAME ": "
>  #define DFX DRV_NAME "%d: "
>  
> diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
> index b9732b1..a3e0f69 100644
> --- a/drivers/scsi/fnic/fnic_scsi.c
> +++ b/drivers/scsi/fnic/fnic_scsi.c
> @@ -2041,7 +2041,9 @@ lr_io_req_end:
>   * successfully aborted, 1 otherwise
>   */
>  static int fnic_clean_pending_aborts(struct fnic *fnic,
> -  struct scsi_cmnd *lr_sc)
> +  struct scsi_cmnd *lr_sc,
> +  bool new_sc)
> +

I don't see that this or any of the subsequent patches do anything with
this argument except pass 0 to it.  So why add it?

>  {
>   int tag, abt_tag;
>   struct fnic_io_req *io_req;
> @@ -2059,10 +2061,10 @@ static int fnic_clean_pending_aborts(struct fnic 
> *fnic,
>   spin_lock_irqsave(io_lock, flags);
>   sc = scsi_host_find_tag(fnic->lport->host, tag);
>   /*
> -  * ignore this lun reset cmd or cmds that do not belong to
> -  * this lun
> +  * ignore this lun reset cmd if issued using new SC
> +  * or cmds that do not belong to this lun
>*/
> - if (!sc || sc == lr_sc || sc->device != lun_dev) {
> + if (!sc || ((sc == lr_sc) && new_sc) || sc->device != lun_dev) {
>   spin_unlock_irqrestore(io_lock, flags);
>   continue;
>   }
> @@ -2168,11 +2170,27 @@ static int fnic_clean_pending_aborts(struct fnic 
> *fnic,
>   goto clean_pending_aborts_end;
>   }
>   CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
> - CMD_SP(sc) = NULL;
> +
> + /* original sc used for lr is handled by dev reset code */
> + if (sc != lr_sc)
> + CMD_SP(sc) = NULL;
>   spin_unlock_irqrestore(io_lock, flags);
>  
> - fnic_release_ioreq_buf(fnic, io_req, sc);
> - mempool_free(io_req, fnic->io_req_pool);
> + /* original sc used for lr is handled by dev reset code */
> + if (sc != lr_sc) {
> + fnic_release_ioreq_buf(fnic, io_req, sc);
> + mempool_free(io_req, fnic->io_req_pool);
> + }
> +
> + /*
> +  * Any IO is returned during reset, it needs to call scsi_done
> +  * to return the scsi_cmnd to upper layer.
> +  */
> + if (sc->scsi_done) {
> + /* Set result to let upper SCSI layer retry */
> + sc->result = DID_RESET << 16;
> + sc->scsi_done(sc);
> + }
>   }
>  
>   schedule_timeout(msecs_to_jiffies(2 * fnic->config.ed_tov));
> @@ -2266,6 +2284,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
>   int tag = 0;
>   DECLARE_COMPLETION_ONSTACK(tm_done);
>   int tag_gen_flag = 0;   /*to track tags allocated by fnic driver*/
> + bool new_sc = 0;
>  
>   /* Wait for rport to unblock */
>   fc_block_scsi_eh(sc);
> @@ -2452,7 +2471,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
>* the lun reset cmd. If all cmds get cleaned, the lun reset
>* succeeds
>*/
> - if (fnic_clean_pending_aborts(fnic, sc)) {
> + if (fnic_clean_pending_aborts(fnic, sc, new_sc)) {
>   spin_lock_irqsave(io_lock, flags);
>   io_req = (struct fnic_io_req *)CMD_SP(sc);
>   FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 1/5] Fix to cleanup aborted IO to avoid device being offlined by mid-layer

2016-03-14 Thread Ewan Milne
On Mon, 2016-03-14 at 11:14 -0700, Satish Kharat wrote:
> If an I/O times out and an abort issued by host, if the abort is
> successful we need to set scsi status as DID_ABORT. Or else the
> mid-layer error handler which looks for this error code, will
> offline the device. Also if the original I/O is not found in fnic
> firmware, we will consider the abort as successful.
> Fnic driver version changed from 1.6.0.17a to 1.6.0.19,
> version 1.6.0.18 has been skipped
> 
> Signed-off-by: Satish Kharat 
> ---
>  drivers/scsi/fnic/fnic.h  |  2 +-
>  drivers/scsi/fnic/fnic_scsi.c | 32 +++-
>  2 files changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
> index ce129e5..52a53f8 100644
> --- a/drivers/scsi/fnic/fnic.h
> +++ b/drivers/scsi/fnic/fnic.h
> @@ -39,7 +39,7 @@
>  
>  #define DRV_NAME "fnic"
>  #define DRV_DESCRIPTION  "Cisco FCoE HBA Driver"
> -#define DRV_VERSION  "1.6.0.17a"
> +#define DRV_VERSION  "1.6.0.19"
>  #define PFX  DRV_NAME ": "
>  #define DFX DRV_NAME "%d: "
>  
> diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
> index 266b909..b9732b1 100644
> --- a/drivers/scsi/fnic/fnic_scsi.c
> +++ b/drivers/scsi/fnic/fnic_scsi.c
> @@ -1092,6 +1092,11 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic 
> *fnic,
>   atomic64_inc(
>   &term_stats->terminate_fw_timeouts);
>   break;
> + case FCPIO_ITMF_REJECTED:
> + FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
> + "abort reject recd. id %d\n",
> + (int)(id & FNIC_TAG_MASK));
> + break;
>   case FCPIO_IO_NOT_FOUND:
>   if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED)
>   atomic64_inc(&abts_stats->abort_io_not_found);
> @@ -1112,9 +1117,14 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic 
> *fnic,
>   spin_unlock_irqrestore(io_lock, flags);
>   return;
>   }
> +
>   CMD_ABTS_STATUS(sc) = hdr_status;
>   CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE;
>  
> + /* If the status is IO not found consider it as success */
> + if (hdr_status == FCPIO_IO_NOT_FOUND)
> + CMD_ABTS_STATUS(sc) = FCPIO_SUCCESS;
> +

Minor nitpick:  I would have done:

if (hdr_status == FCP_IO_NOT_FOUND)
CMD_ABTS_STATUS(sc) = FCPIO_SUCCESS;
else
CMD_ABTS_STATUS(sc) = hdr_status;

rather than overwriting the assignment made several lines above, it is
more explicit and less prone to errors if the code is later changed.

>   atomic64_dec(&fnic_stats->io_stats.active_ios);
>   if (atomic64_read(&fnic->io_cmpl_skip))
>   atomic64_dec(&fnic->io_cmpl_skip);
> @@ -1927,21 +1937,33 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
>  
>   CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
>  
> + start_time = io_req->start_time;
>   /*
>* firmware completed the abort, check the status,
> -  * free the io_req irrespective of failure or success
> +  * free the io_req if successful. If abort fails,
> +  * Device reset will clean the I/O.
>*/
> - if (CMD_ABTS_STATUS(sc) != FCPIO_SUCCESS)
> + if (CMD_ABTS_STATUS(sc) == FCPIO_SUCCESS) {
> + CMD_SP(sc) = NULL;
> + }
> + else
> + {
>   ret = FAILED;
> -
> - CMD_SP(sc) = NULL;
> + spin_unlock_irqrestore(io_lock, flags);
> + goto fnic_abort_cmd_end;
> + }
>  
>   spin_unlock_irqrestore(io_lock, flags);
>  
> - start_time = io_req->start_time;

What was the point of moving the assignment of start_time?
Other places in the code still set it just before the call to
fnic_release_ioreq_buf().

>   fnic_release_ioreq_buf(fnic, io_req, sc);
>   mempool_free(io_req, fnic->io_req_pool);
>  
> + if (sc->scsi_done) {
> + /* Call SCSI completion function to complete the IO */
> + sc->result = (DID_ABORT << 16);
> + sc->scsi_done(sc);
> + }
> +
>  fnic_abort_cmd_end:
>   FNIC_TRACE(fnic_abort_cmd, sc->device->host->host_no,
> sc->request->tag, sc,

Despite the above comments, I guess this looks OK.

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 2/3] lpfc: fix misleading indentation

2016-03-14 Thread Ewan Milne
On Mon, 2016-03-14 at 16:26 +0100, Hannes Reinecke wrote:
> On 03/14/2016 04:25 PM, Arnd Bergmann wrote:
> > On Monday 14 March 2016 16:19:58 Hannes Reinecke wrote:
> >>>   vports = lpfc_create_vport_work_array(phba);
> >>> - if (vports != NULL)
> >>> + if (vports != NULL) {
> >>>   for (i = 0; i <= phba->max_vports && vports[i] != NULL; 
> >>> i++) {
> >>>   struct Scsi_Host *shost;
> >>>   shost = lpfc_shost_from_vport(vports[i]);
> >>> @@ -2877,7 +2877,8 @@ lpfc_online(struct lpfc_hba *phba)
> >>>   }
> >>>   spin_unlock_irq(shost->host_lock);
> >>>   }
> >>> - lpfc_destroy_vport_work_array(phba, vports);
> >>> + }
> >>> + lpfc_destroy_vport_work_array(phba, vports);
> >>>  
> >>>   lpfc_unblock_mgmt_io(phba);
> >>>   return 0;
> >>>
> >> Nope.
> >>
> >> vports is only valid from within the indentation block, so it should
> >> be moved into it.
> >>
> >>
> > 
> > Well, every other user of the function also looks like
> > 
> > vports = lpfc_create_vport_work_array(phba);
> > if (vports != NULL) {
> > do_something(vports);
> > }
> > lpfc_destroy_vport_work_array(phba, vports);

Actually the lpfc code is inconsistent about whether the _destroy call
is within the (vports != NULL) test or not, but as you say below it
doesn't matter.

Reviewed-by: Ewan D. Milne 

> > 
> > and lpfc_destroy_vport_work_array() does nothing if its argument is NULL.
> > 
> > I still think my patch is the correct fix for the warning.
> > 
> Okay, good point.
> 
> Reviewed-by: Hannes Reinecke 
> 
> Cheers,
> 
> Hannes


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


Re: [PATCH] Avoid that long log lines are truncated

2016-03-14 Thread Ewan Milne
On Mon, 2016-03-14 at 07:19 -0700, Bart Van Assche wrote:
> While testing the latest version of the SRP initiator and target
> drivers I encountered the following message in the kernel log:
> 
> sd 16:0:0:0: Warning! Received an indication that the LUN assignments on this 
> target have changed. The Linux SCSI layer does not automatical
> 
> This is a truncated message. Avoid that such truncation happens
> by increasing the SCSI_LOG_BUFSIZE constant.
> 
> Fixes: ded85c193a39 (scsi: Implement per-cpu logging buffer)
> Signed-off-by: Bart Van Assche 
> Cc: Hannes Reinecke 
> Cc: Christoph Hellwig 
> Cc: Robert Elliott 
> Cc: Ewan D. Milne 
> Cc:  # v4.0+
> ---
>  include/scsi/scsi_dbg.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
> index 56710e0..05d36eb 100644
> --- a/include/scsi/scsi_dbg.h
> +++ b/include/scsi/scsi_dbg.h
> @@ -5,7 +5,7 @@ struct scsi_cmnd;
>  struct scsi_device;
>  struct scsi_sense_hdr;
>  
> -#define SCSI_LOG_BUFSIZE 128
> +#define SCSI_LOG_BUFSIZE 256
>  
>  extern void scsi_print_command(struct scsi_cmnd *);
>  extern size_t __scsi_format_command(char *, size_t,

Hmm.  Perhaps we should make the message less verbose instead?
It looks like if we increase SCSI_LOG_BUFSIZE then we get fewer
per-message buffers unless we also increase SCSI_LOG_SPOOLSIZE.

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] megaraid_sas: Don't issue kill adapter for MFI controllers in case of PD list DCMD failure

2016-03-10 Thread Ewan Milne
On Thu, 2016-03-10 at 02:14 -0800, Sumit Saxena wrote:
> There are few MFI adapters which do not support MR_DCMD_PD_LIST_QUERY so
> if MFI adapters fail this DCMD, it should not be considered as FATAL and
> driver should not issue kill adapter and set per controller's instance
> variable- pd_list_not_supported so that same variable can be used inside
> functions- slave_alloc and slave_configure to allow firmware scan.
> 
> Killing adapter because of DCMD failure when this DCMD is not supported
> causes driver's probe getting failed. This issue got introduced because
> of below commit when MFI IO timeout handling was introduced-
> 
> 6d40afb megaraid_sas: MFI IO timeout handling
> 
> Killing adapter in case of this DCMD failure should be limited to Fusion
> adapters only. Per controller's instance variable allow_fw_scan is removed
> as pd_list_not_supported better reflect the purpose.
> 
> Signed-off-by: Sumit Saxena 
> ---
>  drivers/scsi/megaraid/megaraid_sas.h  |  2 +-
>  drivers/scsi/megaraid/megaraid_sas_base.c | 14 ++
>  2 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
> b/drivers/scsi/megaraid/megaraid_sas.h
> index 4484e63..fce414a 100644
> --- a/drivers/scsi/megaraid/megaraid_sas.h
> +++ b/drivers/scsi/megaraid/megaraid_sas.h
> @@ -2097,7 +2097,7 @@ struct megasas_instance {
>   u8 UnevenSpanSupport;
>  
>   u8 supportmax256vd;
> - u8 allow_fw_scan;
> + u8 pd_list_not_supported;
>   u16 fw_supported_vd_count;
>   u16 fw_supported_pd_count;
>  
> diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
> b/drivers/scsi/megaraid/megaraid_sas_base.c
> index 5c08568..69d375b 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_base.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_base.c
> @@ -1838,7 +1838,7 @@ static int megasas_slave_configure(struct scsi_device 
> *sdev)
>   struct megasas_instance *instance;
>  
>   instance = megasas_lookup_instance(sdev->host->host_no);
> - if (instance->allow_fw_scan) {
> + if (instance->pd_list_not_supported) {
>   if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
>   sdev->type == TYPE_DISK) {
>   pd_index = (sdev->channel * 
> MEGASAS_MAX_DEV_PER_CHANNEL) +
> @@ -1874,7 +1874,8 @@ static int megasas_slave_alloc(struct scsi_device *sdev)
>   pd_index =
>   (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
>   sdev->id;
> - if ((instance->allow_fw_scan || 
> instance->pd_list[pd_index].driveState ==
> + if ((instance->pd_list_not_supported ||
> + instance->pd_list[pd_index].driveState ==
>   MR_PD_STATE_SYSTEM)) {
>   goto scan_target;
>   }
> @@ -4087,7 +4088,13 @@ megasas_get_pd_list(struct megasas_instance *instance)
>  
>   switch (ret) {
>   case DCMD_FAILED:
> - megaraid_sas_kill_hba(instance);
> + dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY "
> + "failed/not supported by firmware\n");
> +
> + if (instance->ctrl_context)
> + megaraid_sas_kill_hba(instance);
> + else
> + instance->pd_list_not_supported = 1;
>   break;
>   case DCMD_TIMEOUT:
>  
> @@ -5034,7 +5041,6 @@ static int megasas_init_fw(struct megasas_instance 
> *instance)
>   case PCI_DEVICE_ID_DELL_PERC5:
>   default:
>   instance->instancet = &megasas_instance_template_xscale;
> - instance->allow_fw_scan = 1;
>   break;
>   }
>  

Note the comment "fixes 6d40afb megaraid_sas: MFI IO timeout handling"

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] scsi_sysfs: Fix typo in is_bin_visible()

2016-03-10 Thread Ewan Milne
On Thu, 2016-03-10 at 11:25 +0100, Hannes Reinecke wrote:
> The test for the existence vpd_pg83 is inverted.
> 
> Fixes: 7e47976bcff ("scsi_sysfs: add 'is_bin_visible' callback")
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/scsi_sysfs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
> index 58ac9c1..d805d55 100644
> --- a/drivers/scsi/scsi_sysfs.c
> +++ b/drivers/scsi/scsi_sysfs.c
> @@ -1105,7 +1105,7 @@ static umode_t scsi_sdev_bin_attr_is_visible(struct 
> kobject *kobj,
>   if (attr == &dev_attr_vpd_pg80 && !sdev->vpd_pg80)
>   return 0;
>  
> - if (attr == &dev_attr_vpd_pg83 && sdev->vpd_pg83)
> + if (attr == &dev_attr_vpd_pg83 && !sdev->vpd_pg83)
>   return 0;
>  
>   return S_IRUGO;

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] sg: fix dxferp in from_to case

2016-03-09 Thread Ewan Milne
On Thu, 2016-03-03 at 00:31 -0500, Douglas Gilbert wrote:
> This patch is in response to this report:
> http://www.spinics.net/lists/linux-scsi/msg93456.html
> 
> One of the strange things that the original sg driver did was let
> the user provide both a data-out buffer (it followed the
> sg_header+cdb) _and_ specify a reply length greater than zero. What
> happened was that the user data-out buffer was copied into some
> kernel buffers and then the mid level was told a read type operation
> would take place with the data from the device overwriting the same
> kernel buffers. The user would then read those kernel buffers back
> into the user space.
> 
>  From what I can tell, the above action was broken by a change in
> 2008 and syzkaller found that out recently.
> 
> ChangeLog:
>make sure that a user space pointer is passed through
>when data follows the sg_header structure and command.
>Fix the abnormal case when a non-zero reply_len is also
>given.
> 
> Signed-off-by: Douglas Gilbert 

This looks correct to me.  hp->dxferp used to be set unconditionally,
but commit fad7f01e changed it to only be set in the SG_DXFER_TO_DEV
case.

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] sd: Fix discard granularity when LBPRZ=1

2016-03-07 Thread Ewan Milne
On Sat, 2016-03-05 at 18:10 -0500, Martin K. Petersen wrote:
> Commit 397737223c59 ("sd: Make discard granularity match logical block
> size when LBPRZ=1") accidentally set the granularity to one byte instead
> of one logical block on devices that provide determistic zeroes after
> UNMAP.
> 
> Signed-off-by: Martin K. Petersen 
> Reported-by: Mike Snitzer 
> Fixes: 397737223c59e89dca7305feb6528caef8fbef84
> Cc:  # 4.4+
> ---
>  drivers/scsi/sd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index d749da765df1..5a5457ac9cdb 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -648,7 +648,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, 
> unsigned int mode)
>*/
>   if (sdkp->lbprz) {
>   q->limits.discard_alignment = 0;
> - q->limits.discard_granularity = 1;
> + q->limits.discard_granularity = logical_block_size;
>   } else {
>   q->limits.discard_alignment = sdkp->unmap_alignment *
>   logical_block_size;

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 0/2][RESEND] scsi_transport_fc: LUN masking

2016-03-01 Thread Ewan Milne
On Tue, 2016-02-23 at 18:21 +0800, Hannes Reinecke wrote:
> On 02/22/2016 07:39 PM, Seymour, Shane M wrote:
> > Hi Hannes,
> > 
> > How do you know that a request for an async scan is complete (I'm assuming 
> > that you get
> > add or change udev events)? Assuming that someone has manually started a 
> > scan on something
> > (e.g. some newly presented devices after boot) and all scans are going
> to be async how
> > do you when it is complete rather than waiting in a work queue? An
> example may be a sysfs
> > file that contains unscanned, pending, scanning, scanned so you know
> when it's complete
> > at the appropriate level in sysfs (the hba and the rports) so you know
> when can continue
> > if you're polling the status (e.g. checking as part of system admin
> work with newly
> > presented rports so you can then do something with them).
> >
> Thing is, I don't.
> 
> We have had a similar discussion with the IBM zfcp folks, that it would
> be desirable to have a marker in sysfs telling us that the rport is
> stable (ie no scanning in progress).
> However, this cannot be at the rport level (as the rport itself might be
> going away), but rather at some higher level (eg fc_host).

I am not sure this really helps.  If another process initiates a scan
then sysfs might report that the scanning was still in progress.  If
scans are initiated often enough, you might never observe a stable state.

> 
> But this has nothing to do with the patchset, right?
> We're just disabling the (existing) scan callback, and retrigger it once
> the sysfs attribute has been cleared.
> 
> We don't change the behaviour during scanning with this patchset.
> 
> Cheers,
> 
> Hannes


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


Re: [PATCH] snic: correctly check for array overrun on overly long version number

2016-03-01 Thread Ewan Milne
On Thu, 2016-02-25 at 22:58 +, Colin King wrote:
> From: Colin Ian King 
> 
> The snic version number is expected to be 4 decimals in the form like
> a netmask string with each number stored in an element in array v.
> However, there is an off-by-one check on the number of elements in v
> allowing one to pass a 5 decimal version number causing v[4] to be
> referenced, causing a buffer overrun.  Fix the off-by-one error by
> comparing to i > 3 rather than 4.
> 
> Signed-off-by: Colin Ian King 
> ---
>  drivers/scsi/snic/snic_ctl.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/snic/snic_ctl.c b/drivers/scsi/snic/snic_ctl.c
> index aebe753..ab0e06b 100644
> --- a/drivers/scsi/snic/snic_ctl.c
> +++ b/drivers/scsi/snic/snic_ctl.c
> @@ -75,7 +75,7 @@ snic_ver_enc(const char *s)
>   continue;
>   }
>  
> - if (i > 4 || !isdigit(c))
> + if (i > 3 || !isdigit(c))
>   goto end;
>  
>   v[i] = v[i] * 10 + (c - '0');

int v[4] = {0};

So clearly the i > 4 test is wrong and should be i > 3.

Reviewed-by: Ewan D. Milne 


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


Re: [PATCHv8 20/23] scsi: Add 'access_state' attribute

2016-02-23 Thread Ewan Milne
On Tue, 2016-02-23 at 18:27 +0800, Hannes Reinecke wrote:
> On 02/22/2016 11:34 PM, Bart Van Assche wrote:
> > On 02/21/16 22:59, Hannes Reinecke wrote:
> >> The main reason why I need the 'access_state' attribute is to decouple
> >> the multipath daemon; at the moment the multipath daemon has to issue
> >> REPORT TARGET PORT GROUPS frequently to figure out the status, which is
> >> causing quite some load on the target. When using the 'access_state'
> >> attribute we would avoid doing I/O for that and have a consistent view,
> >> both on the kernel and the multipath daemon side.
> >>
> >> But it's actually a good thing to have the 'access_state' patch in a
> >> different series; I've got some more patches converting the remaining
> >> device_handler to also supply the 'access_state' values.
> > 
> > Hello Hannes,
> > 
> > The above sounds very interesting to me. Will multipathd recognize at
> > run-time whether or not the kernel supports the sysfs ALUA state
> > attribute ?
> That was the plan.
> (Not that I've got any idea _how_ to do this ATM :-)
> 
> > Will ALUA state changes be reported through udev or will
> > multipathd poll the sysfs ALUA state attributes ? 
> Polling. udev events will be too unreliable here, as each uevent
> potentially causes I/O during uevent processing which might stall as the
> path might be down.
> So we might never get events for failed/transitioning paths, however,
> these are precisely the cases which we're interested in ...

And, in fact, if paths go down due to e.g. an FC switch failure, it is
common for a large number of paths to go down at once, causing a large
number of uevents to be queued.

> 
> > And if the netlink
> > buffer that is used in multipathd to receive udev events overflows
> > (ENOBUFS), will multipathd resynchronize its state ? As far as I can see
> > in source file libmultipath/uevent.c today multipathd ignores netlink
> > buffer overflows.
> > 
> Which, thankfully, doesn't apply as multipathd will be polling the sysfs
> attribute directly :-)
> 
> Cheers,
> 
> Hannes


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


Re: [PATCH v2] fusion-mptbase: handle failed allocation for workqueue

2016-02-18 Thread Ewan Milne
On Thu, 2016-02-18 at 11:40 -0500, Ewan Milne wrote:
> It also appears to me upon further inspection that the existing code has
> other problems.  In particular, once mpt_mapresources() has returned
> with a nonzero error code, it looks like iounmap() should be called, but
> it is not in the case of a failed allocation of reset_work_q.  I'm also
> not sure why pci_release_selected_regions() is only called for the case
> of mpt_do_ioc_recovery() returning != -5 when it is called whenever
> there is a failed allocation of reset_work_q.
> 
> Consider the attached patch (untested, because I don't have hardware):
> It shows what I would do for labels & error handling.  If the rc != -5
> case of return from mpt_do_ioc_recovery() could be eliminated, then
> another label "out_free_fw_event_q:" could be added prior to the other
> error cases at the end, and all the code after the printk() in that path
> could be replaced by "goto out_free_fw_event_q;"
> 
>   if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
>   CAN_SLEEP)) != 0){
>   printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
>   ioc->name, r);
>   goto out_free_fw_event_q;
>   }
> ...
> 
> out_free_fw_event_q:
>   destroy_workqueue(ioc->fw_event_q);
>   ioc->fw_event_q = NULL;
> 
> out_remove_ioc:
> ...
> 
> However I do not know if that change is legitimate.
> 
> -Ewan

There is an error in the patch attached in my previous mail.
Please refer to the attached PATCH v2 RFC.

-Ewan

>From 79fd59c66c3afb339cf9fdd1fda65e78e32831a4 Mon Sep 17 00:00:00 2001
From: "Ewan D. Milne" 
Date: Thu, 18 Feb 2016 11:49:37 -0500
Subject: [PATCH v2 RFC] mptbase: fixup error handling paths in mpt_attach()

mpt_attach() was not checking for the failure to create fw_event_q.
Also, iounmap() was not being called in all error cases after ioremap()
had been called by mpt_mapresources().
---
 drivers/message/fusion/mptbase.c | 37 +++--
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 5dcc031..a4f362b 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1801,8 +1801,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	ioc->pcidev = pdev;
 	if (mpt_mapresources(ioc)) {
-		kfree(ioc);
-		return r;
+		goto out_free_ioc;
 	}
 
 	/*
@@ -1871,9 +1870,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (!ioc->reset_work_q) {
 		printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
 		ioc->name);
-		pci_release_selected_regions(pdev, ioc->bars);
-		kfree(ioc);
-		return -ENOMEM;
+		r = -ENOMEM;
+		goto out_unmap_resources;
 	}
 
 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
@@ -1995,12 +1993,21 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 	spin_lock_init(&ioc->fw_event_lock);
 	snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
 	ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
+	if (!ioc->fw_event_q) {
+		printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
+		ioc->name);
+		r = -ENOMEM;
+		goto out_remove_ioc;
+	}
 
 	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
 	CAN_SLEEP)) != 0){
 		printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
 		ioc->name, r);
 
+		destroy_workqueue(ioc->fw_event_q);
+		ioc->fw_event_q = NULL;
+
 		list_del(&ioc->list);
 		if (ioc->alt_ioc)
 			ioc->alt_ioc->alt_ioc = NULL;
@@ -2040,6 +2047,24 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 			msecs_to_jiffies(MPT_POLLING_INTERVAL));
 
 	return 0;
+
+out_remove_ioc:
+	list_del(&ioc->list);
+	if (ioc->alt_ioc)
+		ioc->alt_ioc->alt_ioc = NULL;
+	pci_set_drvdata(ioc->pcidev, NULL);
+
+	destroy_workqueue(ioc->reset_work_q);
+	ioc->reset_work_q = NULL;
+
+out_unmap_resources:
+	iounmap(ioc->memmap);
+	pci_release_selected_regions(pdev, ioc->bars);
+
+out_free_ioc:
+	kfree(ioc);
+
+	return r;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6229,7 +6254,7 @@ mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
 	memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
 	memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
 
-	out:
+out:
 
 	if (pbuf)
 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
-- 
2.1.0



Re: [PATCH v2] fusion-mptbase: handle failed allocation for workqueue

2016-02-18 Thread Ewan Milne
On Thu, 2016-02-18 at 10:00 +0100, Johannes Thumshirn wrote:
> On Wed, Feb 17, 2016 at 11:40:59PM -0500, Insu Yun wrote:
> > the failure of ioc->reset_work_q is checked,
> > but not ioc->fw_event_q.
> > 
> > Signed-off-by: Insu Yun 
> > ---
> >  drivers/message/fusion/mptbase.c | 44 
> > 
> >  1 file changed, 27 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/message/fusion/mptbase.c 
> > b/drivers/message/fusion/mptbase.c
> > index 5dcc031..53a5015 100644
> > --- a/drivers/message/fusion/mptbase.c
> > +++ b/drivers/message/fusion/mptbase.c
> > @@ -1871,9 +1871,8 @@ mpt_attach(struct pci_dev *pdev, const struct 
> > pci_device_id *id)
> > if (!ioc->reset_work_q) {
> > printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
> > ioc->name);
> > -   pci_release_selected_regions(pdev, ioc->bars);
> > -   kfree(ioc);
> > -   return -ENOMEM;
> > +   r = -ENOMEM;
> > +   goto err3;
> > }
> >  
> > dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
> > @@ -1996,24 +1995,16 @@ mpt_attach(struct pci_dev *pdev, const struct 
> > pci_device_id *id)
> > snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
> > ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
> >  
> > +   if (!ioc->fw_event_q) {
> > +   r = -ENOMEM;
> > +   goto err2;
> > +   }
> > +
> > if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
> > CAN_SLEEP)) != 0){
> > printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
> > ioc->name, r);
> > -
> > -   list_del(&ioc->list);
> > -   if (ioc->alt_ioc)
> > -   ioc->alt_ioc->alt_ioc = NULL;
> > -   iounmap(ioc->memmap);
> > -   if (r != -5)
> > -   pci_release_selected_regions(pdev, ioc->bars);
> > -
> > -   destroy_workqueue(ioc->reset_work_q);
> > -   ioc->reset_work_q = NULL;
> > -
> > -   kfree(ioc);
> > -   pci_set_drvdata(pdev, NULL);
> > -   return r;
> > +   goto err1;
> > }
> >  
> > /* call per device driver probe entry point */
> > @@ -2040,6 +2031,25 @@ mpt_attach(struct pci_dev *pdev, const struct 
> > pci_device_id *id)
> > msecs_to_jiffies(MPT_POLLING_INTERVAL));
> >  
> > return 0;
> > +
> > +err1:
> > +   destroy_workqueue(ioc->fw_event_q);
> > +   ioc->fw_event_q = NULL;
> > +err2::
> > +   destroy_workqueue(ioc->reset_work_q);
> > +   ioc->reset_work_q = NULL;
> > +
> > +   list_del(&ioc->list);
> > +   if (ioc->alt_ioc)
> > +   ioc->alt_ioc->alt_ioc = NULL;
> > +   iounmap(ioc->memmap);
> > +   pci_set_drvdata(pdev, NULL);
> > +err3:
> > +   if (r != -5)
> > +   pci_release_selected_regions(pdev, ioc->bars);
> > +   kfree(ioc);
> > +   return r;
> > +
> >  }
> 
> Please no. Not err1, err2 and err3.
> 
> err1 could be "goto destroy_fw_event_q", err2 "destroy_reset_workq", err3
> goto "free_ioc".

It also appears to me upon further inspection that the existing code has
other problems.  In particular, once mpt_mapresources() has returned
with a nonzero error code, it looks like iounmap() should be called, but
it is not in the case of a failed allocation of reset_work_q.  I'm also
not sure why pci_release_selected_regions() is only called for the case
of mpt_do_ioc_recovery() returning != -5 when it is called whenever
there is a failed allocation of reset_work_q.

Consider the attached patch (untested, because I don't have hardware):
It shows what I would do for labels & error handling.  If the rc != -5
case of return from mpt_do_ioc_recovery() could be eliminated, then
another label "out_free_fw_event_q:" could be added prior to the other
error cases at the end, and all the code after the printk() in that path
could be replaced by "goto out_free_fw_event_q;"

if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
CAN_SLEEP)) != 0){
printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
ioc->name, r);
goto out_free_fw_event_q;
}
...

out_free_fw_event_q:
destroy_workqueue(ioc->fw_event_q);
ioc->fw_event_q = NULL;

out_remove_ioc:
...

However I do not know if that change is legitimate.

-Ewan

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

>From 83f117b81d58d01bfe7e01e04e4f2f2a602e2c9f Mon Sep 17 00:00:00 2001
From: "Ewan D. Milne" 
Date: Thu, 18 Feb 2016 11:24:02 -0500
S

Re: [PATCH] fusion-mptbase: handle failed allocation for workqueue

2016-02-16 Thread Ewan Milne
On Tue, 2016-02-16 at 13:33 -0500, Insu Yun wrote:
> 
> 
> On Tue, Feb 16, 2016 at 1:18 PM, Ewan Milne  wrote:
> On Mon, 2016-02-15 at 21:50 -0500, Insu Yun wrote:
> > the failure of ioc->reset_work_q is checked,
> > but not ioc->fw_event_q.
> >
> > Signed-off-by: Insu Yun 
> > ---
> >  drivers/message/fusion/mptbase.c | 7 +++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/drivers/message/fusion/mptbase.c
> b/drivers/message/fusion/mptbase.c
> > index 5dcc031..d4907a1 100644
> > --- a/drivers/message/fusion/mptbase.c
> > +++ b/drivers/message/fusion/mptbase.c
> > @@ -1996,6 +1996,13 @@ mpt_attach(struct pci_dev *pdev,
> const struct pci_device_id *id)
> >   snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN,
> "mpt/%d", ioc->id);
> >   ioc->fw_event_q =
> create_singlethread_workqueue(ioc->fw_event_q_name);
> >
> > + if (!ioc->fw_event_q) {
> > + destroy_workqueue(ioc->reset_work_q);
> > + pci_release_selected_regions(pdev, ioc->bars);
> > + kfree(ioc);
> > + return -ENOMEM;
> > + }
> > +
> >   if ((r = mpt_do_ioc_recovery(ioc,
> MPT_HOSTEVENT_IOC_BRINGUP,
> >   CAN_SLEEP)) != 0){
> >   printk(MYIOC_s_ERR_FMT "didn't initialize
> properly! (%d)\n",
> 
> This does not look correct to me.  The error path for the call
> to
> mpt_do_ioc_recovery() after create_singlethread_workqueue()
> for
> ioc->fw_event_q does other cleanup, including:
> 
> list_del(&ioc->list);
> if (ioc->alt_ioc)
> ioc->alt_ioc->alt_ioc = NULL;
> iounmap(ioc->memmap);
> 
> and
> 
> kfree(ioc);
> pci_set_drvdata(pdev, NULL);
> 
> 
> Oh yes. Right. 
> I just copied from above error handling code.
> 
> 
>  
> 
> Here I think you are kfree()ing ioc while it is still on the
> &ioc_list,
> which will cause a crash.
> 
> Note to Avago:  this code could use a symbolic return code
> identifier:
> 
> if (r != -5)
> pci_release_selected_regions(pdev,
> ioc->bars);
> 
> 
> What is -5? it seems strange for me.
> 
> Is it error code? then it is better to use macro.

The comments above mpt_do_ioc_recovery() say:

 *  Returns:

   
 *   0 for success  

   
 *  -1 if failed to get board READY 

   
 *  -2 if READY but IOCFacts Failed 

   
 *  -3 if READY but PrimeIOCFifos Failed

   
 *  -4 if READY but IOCInit Failed  

   
 *  -5 if failed to enable_device and/or request_selected_regions   

   
 *  -6 if failed to upload firmware

and yes, it would be better to use a macro (symbolic value) hence my
comment to Avago.   

   
> 
> 
> 
> In general, with sequential allocation of resources like this,

Re: [PATCH] fusion-mptbase: handle failed allocation for workqueue

2016-02-16 Thread Ewan Milne
On Mon, 2016-02-15 at 21:50 -0500, Insu Yun wrote:
> the failure of ioc->reset_work_q is checked,
> but not ioc->fw_event_q.
> 
> Signed-off-by: Insu Yun 
> ---
>  drivers/message/fusion/mptbase.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/message/fusion/mptbase.c 
> b/drivers/message/fusion/mptbase.c
> index 5dcc031..d4907a1 100644
> --- a/drivers/message/fusion/mptbase.c
> +++ b/drivers/message/fusion/mptbase.c
> @@ -1996,6 +1996,13 @@ mpt_attach(struct pci_dev *pdev, const struct 
> pci_device_id *id)
>   snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
>   ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
>  
> + if (!ioc->fw_event_q) {
> + destroy_workqueue(ioc->reset_work_q);
> + pci_release_selected_regions(pdev, ioc->bars);
> + kfree(ioc);
> + return -ENOMEM;
> + }
> +
>   if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
>   CAN_SLEEP)) != 0){
>   printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",

This does not look correct to me.  The error path for the call to
mpt_do_ioc_recovery() after create_singlethread_workqueue() for
ioc->fw_event_q does other cleanup, including:

list_del(&ioc->list);
if (ioc->alt_ioc)
ioc->alt_ioc->alt_ioc = NULL;
iounmap(ioc->memmap);

and

kfree(ioc);
pci_set_drvdata(pdev, NULL);

Here I think you are kfree()ing ioc while it is still on the &ioc_list,
which will cause a crash.

Note to Avago:  this code could use a symbolic return code identifier:

if (r != -5)
pci_release_selected_regions(pdev, ioc->bars);

In general, with sequential allocation of resources like this, error
handling can be performed using a series of goto's to labels at the
end of the function that release the resources in reverse order.  This
avoids the duplication of code within the function, and reduces the
chance for errors when the function is later modified.  See init_sd
in drivers/scsi/sd.c for an example.

Reviewed-by: Ewan D. Milne 





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


Re: [PATCH] bio: return EINTR if copying to user space got interrupted

2016-02-12 Thread Ewan Milne
On Fri, 2016-02-12 at 09:39 +0100, Hannes Reinecke wrote:
> Commit 35dc248383bbab0a7203fca4d722875bc81ef091 introduced a check for
> current->mm to see if we have a user space context and only copies data
> if we do. Now if an IO gets interrupted by a signal data isn't copied
> into user space any more (as we don't have a user space context) but
> user space isn't notified about it.
> 
> This patch modifies the behaviour to return -EINTR from bio_uncopy_user()
> to notify userland that a signal has interrupted the syscall, otherwise
> it could lead to a situation where the caller may get a buffer with
> no data returned.
> 
> This can be reproduced by issuing SG_IO ioctl()s in one thread while
> constantly sending signals to it.

Well, this is definitely an improvement, since it now indicates to
the user that there was a problem instead of silently returning with
no data and no error, but it doesn't completely fix the issue.

For one thing, if the SG_IO is performed to a sequential media device,
the I/O is actually performed, and the position changes, it is just the
data that is not copied back.  So e.g. a user program making calls to
read from a tape device that gets signals and retrying on -EINTR will
skip blocks.  There is a similar problem already with SG_IO and
-ERESTARTSYS.  I believe that that only way around this is to mask the
signals.  (This is also problem with non-idempotent commands, such as
COMPARE AND WRITE.)

I should mention that the patch "sg: Fix user memory corruption when
SG_IO is interrupted by a signal" broke a 3rd-party kernel module that
happened to use SG_IO to pass *kernel* addresses for I/O.  Which worked
for them until the current->mm test was added.  (I don't know why they
didn't just put I/O on the request queue like everyone else, though.)

This patch should go in, though.

Reviewed-by: Ewan D. Milne 

> 
> Fixes: 35dc248 [SCSI] sg: Fix user memory corruption when SG_IO is 
> interrupted by a signal
> Signed-off-by: Johannes Thumshirn 
> Signed-off-by: Hannes Reinecke 
> Cc: sta...@vger.kernel.org # v.3.11+
> ---
>  block/bio.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/block/bio.c b/block/bio.c
> index dbabd48..24e5b69 100644
> --- a/block/bio.c
> +++ b/block/bio.c
> @@ -1090,9 +1090,12 @@ int bio_uncopy_user(struct bio *bio)
>   if (!bio_flagged(bio, BIO_NULL_MAPPED)) {
>   /*
>* if we're in a workqueue, the request is orphaned, so
> -  * don't copy into a random user address space, just free.
> +  * don't copy into a random user address space, just free
> +  * and return -EINTR so user space doesn't expect any data.
>*/
> - if (current->mm && bio_data_dir(bio) == READ)
> + if (!current->mm)
> + ret = -EINTR;
> + else if (bio_data_dir(bio) == READ)
>   ret = bio_copy_to_iter(bio, bmd->iter);
>   if (bmd->is_our_pages)
>   bio_free_pages(bio);


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


Re: [PATCH 22/23] scsi_dh_alua: update 'access_state' field

2016-02-11 Thread Ewan Milne
On Mon, 2016-02-08 at 15:34 +0100, Hannes Reinecke wrote:
> Track attached SCSI devices and update the 'access_state' field
> whenever an ALUA state change has been detected.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 45 
> --
>  1 file changed, 43 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 51126b78..7bcc075 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -75,6 +76,7 @@ struct alua_port_group {
>   struct kref kref;
>   struct rcu_head rcu;
>   struct list_headnode;
> + struct list_headdh_list;
>   unsigned char   device_id_str[256];
>   int device_id_len;
>   int group_id;
> @@ -92,6 +94,7 @@ struct alua_port_group {
>  };
>  
>  struct alua_dh_data {
> + struct list_headnode;
>   struct alua_port_group  *pg;
>   int group_id;
>   spinlock_t  pg_lock;
> @@ -247,6 +250,7 @@ struct alua_port_group *alua_alloc_pg(struct scsi_device 
> *sdev,
>   INIT_DELAYED_WORK(&pg->rtpg_work, alua_rtpg_work);
>   INIT_LIST_HEAD(&pg->rtpg_list);
>   INIT_LIST_HEAD(&pg->node);
> + INIT_LIST_HEAD(&pg->dh_list);
>   spin_lock_init(&pg->lock);
>  
>   spin_lock(&port_group_lock);
> @@ -328,6 +332,8 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h,
>  {
>   int rel_port = -1, group_id;
>   struct alua_port_group *pg, *old_pg = NULL;
> + bool pg_updated;
> + unsigned long flags;
>  
>   group_id = scsi_vpd_tpg_id(sdev, &rel_port);
>   if (group_id < 0) {
> @@ -357,13 +363,25 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h,
>   old_pg = h->pg;
>   if (old_pg != pg) {
>   /* port group has changed. Update to new port group */
> + if (h->pg) {
> + spin_lock_irqsave(&old_pg->lock, flags);
> + list_del_rcu(&h->node);
> + spin_unlock_irqrestore(&old_pg->lock, flags);
> + }
>   rcu_assign_pointer(h->pg, pg);
> + pg_updated = true;
>   }
>   if (sdev->synchronous_alua)
>   pg->flags |= ALUA_SYNC_STPG;
>   alua_rtpg_queue(h->pg, sdev, NULL, true);
>   spin_unlock(&h->pg_lock);
>  
> + if (pg_updated) {
> + spin_lock_irqsave(&pg->lock, flags);
> + list_add_rcu(&h->node, &pg->dh_list);
> + spin_unlock_irqrestore(&pg->lock, flags);
> + }
> +
>   if (old_pg)
>   kref_put(&old_pg->kref, release_port_group);
>  
> @@ -613,8 +631,18 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg)
>   if (spin_trylock_irqsave(&tmp_pg->lock, flags)) {
>   if ((tmp_pg == pg) ||
>   !(tmp_pg->flags & ALUA_PG_RUNNING)) {
> + struct alua_dh_data *h;
> +
>   tmp_pg->state = desc[0] & 0x0f;
>   tmp_pg->pref = desc[0] >> 7;
> + rcu_read_lock();
> + list_for_each_entry_rcu(h,
> + &tmp_pg->dh_list, node) {
> + /* h->sdev should always be 
> valid */
> + BUG_ON(!h->sdev);
> + h->sdev->access_state = desc[0];

Here you did not mask desc[0] with 0x0f like you did in other places in the 
code.

> + }
> + rcu_read_unlock();
>   }
>   if (tmp_pg == pg)
>   valid_states = desc[1];
> @@ -646,10 +674,19 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg)
>   pg->interval = 2;
>   err = SCSI_DH_RETRY;
>   } else {
> + struct alua_dh_data *h;
> +
>   /* Transitioning time exceeded, set port to standby */
>   err = SCSI_DH_IO;
>   pg->state = SCSI_ACCESS_STATE_STANDBY;
>   pg->expiry = 0;
> + rcu_read_lock();
> + list_for_each_entry_rcu(h, &pg->dh_list, node) {
> + BUG_ON(!h->sdev);
> + h->sdev->access_state = (pg->state & 0x0f) |
> +

Re: [PATCH 20/23] scsi: Add 'access_state' attribute

2016-02-11 Thread Ewan Milne
On Mon, 2016-02-08 at 15:34 +0100, Hannes Reinecke wrote:
> Add an 'access_state' attribute to struct scsi_device to
> display the asymmetric LUN access state.
> 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/scsi_scan.c   |  1 +
>  drivers/scsi/scsi_sysfs.c  | 49 
> ++
>  include/scsi/scsi_device.h |  1 +
>  include/scsi/scsi_proto.h  | 13 
>  4 files changed, 64 insertions(+)
> 
> diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
> index 97074c9..5bf3945 100644
> --- a/drivers/scsi/scsi_scan.c
> +++ b/drivers/scsi/scsi_scan.c
> @@ -231,6 +231,7 @@ static struct scsi_device *scsi_alloc_sdev(struct 
> scsi_target *starget,
>   sdev->lun = lun;
>   sdev->channel = starget->channel;
>   sdev->sdev_state = SDEV_CREATED;
> + sdev->access_state = SCSI_ACCESS_STATE_UNKNOWN;
>   INIT_LIST_HEAD(&sdev->siblings);
>   INIT_LIST_HEAD(&sdev->same_target_siblings);
>   INIT_LIST_HEAD(&sdev->cmd_list);
> diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
> index 4f18a85..8d154ed 100644
> --- a/drivers/scsi/scsi_sysfs.c
> +++ b/drivers/scsi/scsi_sysfs.c
> @@ -81,6 +81,34 @@ const char *scsi_host_state_name(enum scsi_host_state 
> state)
>   return name;
>  }
>  
> +static const struct {
> + enum scsi_access_state  value;
> + char*name;
> +} sdev_access_states[] = {
> + { SCSI_ACCESS_STATE_OPTIMAL, "active/optimized" },
> + { SCSI_ACCESS_STATE_ACTIVE, "active/non-optimized" },
> + { SCSI_ACCESS_STATE_STANDBY, "standby" },
> + { SCSI_ACCESS_STATE_UNAVAILABLE, "unavailable" },
> + { SCSI_ACCESS_STATE_LBA, "lba-dependent" },
> + { SCSI_ACCESS_STATE_OFFLINE, "offline" },
> + { SCSI_ACCESS_STATE_TRANSITIONING, "transitioning" },
> + { SCSI_ACCESS_STATE_UNKNOWN, "unknown" },
> +};
> +
> +const char *scsi_access_state_name(enum scsi_access_state state)
> +{
> + int i;
> + char *name = NULL;
> +
> + for (i = 0; i < ARRAY_SIZE(sdev_access_states); i++) {
> + if (sdev_access_states[i].value == state) {
> + name = sdev_access_states[i].name;
> + break;
> + }
> + }
> + return name;
> +}
> +
>  static int check_set(unsigned long long *val, char *src)
>  {
>   char *last;
> @@ -973,6 +1001,26 @@ sdev_store_dh_state(struct device *dev, struct 
> device_attribute *attr,
>  
>  static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state,
>  sdev_store_dh_state);
> +
> +static ssize_t
> +sdev_show_access_state(struct device *dev,
> +struct device_attribute *attr,
> +char *buf)
> +{
> + struct scsi_device *sdev = to_scsi_device(dev);
> + enum scsi_access_state access_state;
> + bool pref = false;
> +
> + if (sdev->access_state & SCSI_ACCESS_STATE_PREFERRED)
> + pref = true;
> +
> + access_state = (sdev->access_state & SCSI_ACCESS_STATE_MASK);

I personally think it is a mistake to stick an extra bit in the
top of a variable declared as an enum like this.  It opens up
the possibility of subtle bugs if someone changes the code in
the future and does not take care to preserve your extra bit.

> +
> + return snprintf(buf, 32, "%s%s\n",
> + scsi_access_state_name(access_state),
> + pref ? " preferred" : "");
> +}
> +static DEVICE_ATTR(access_state, S_IRUGO, sdev_show_access_state, NULL);
>  #endif
>  
>  static ssize_t
> @@ -1047,6 +1095,7 @@ static struct attribute *scsi_sdev_attrs[] = {
>   &dev_attr_wwid.attr,
>  #ifdef CONFIG_SCSI_DH
>   &dev_attr_dh_state.attr,
> + &dev_attr_access_state.attr,
>  #endif
>   &dev_attr_queue_ramp_up_period.attr,
>   REF_EVT(media_change),
> diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
> index 4af2b24..af16a0d 100644
> --- a/include/scsi/scsi_device.h
> +++ b/include/scsi/scsi_device.h
> @@ -201,6 +201,7 @@ struct scsi_device {
>   struct scsi_device_handler *handler;
>   void*handler_data;
>  
> + enum scsi_access_state  access_state;
>   enum scsi_device_state sdev_state;
>   unsigned long   sdev_data[0];
>  } __attribute__((aligned(sizeof(unsigned long;
> diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h
> index a9fbf1b..80e85e7 100644
> --- a/include/scsi/scsi_proto.h
> +++ b/include/scsi/scsi_proto.h
> @@ -277,5 +277,18 @@ struct scsi_lun {
>   __u8 scsi_lun[8];
>  };
>  
> +/* SPC asymmetric access states */
> +enum scsi_access_state {
> + SCSI_ACCESS_STATE_OPTIMAL = 0,
> + SCSI_ACCESS_STATE_ACTIVE,
> + SCSI_ACCESS_STATE_STANDBY,
> + SCSI_ACCESS_STATE_UNAVAILABLE,
> + SCSI_ACCESS_STATE_LBA,
> + SCSI_ACCESS_STATE_OFFLINE = 0xe,
> + SCSI_ACCESS_STATE_TRANSITIONING = 0xf,
> + SCSI_ACCESS_STATE_UNKNOWN = 0x70,
> +};

Giv

Re: [PATCH 19/23] scsi_dh: add 'rescan' callback

2016-02-11 Thread Ewan Milne
On Mon, 2016-02-08 at 15:34 +0100, Hannes Reinecke wrote:
> If a device needs to be rescanned the device_handler might need
> to be rechecked, too.
> So add a 'rescan' callback to the device handler and call it
> upon scsi_rescan_device().

This comment should mention that you have also changed the Unit
Attention handling of ASC/ASCQ 3F 03 INQUIRY DATA HAS CHANGED
to automatically rescan the device (prior to the uevent).

-Ewan

> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 8 
>  drivers/scsi/scsi_lib.c| 1 +
>  drivers/scsi/scsi_scan.c   | 8 +++-
>  include/scsi/scsi_dh.h | 1 +
>  4 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index a1db82f..56f8d21 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -1038,6 +1038,13 @@ static int alua_prep_fn(struct scsi_device *sdev, 
> struct request *req)
>  
>  }
>  
> +static void alua_rescan(struct scsi_device *sdev)
> +{
> + struct alua_dh_data *h = sdev->handler_data;
> +
> + alua_initialize(sdev, h);
> +}
> +
>  /*
>   * alua_bus_attach - Attach device handler
>   * @sdev: device to be attached to
> @@ -1098,6 +1105,7 @@ static struct scsi_device_handler alua_dh = {
>   .prep_fn = alua_prep_fn,
>   .check_sense = alua_check_sense,
>   .activate = alua_activate,
> + .rescan = alua_rescan,
>   .set_params = alua_set_params,
>  };
>  
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index fa6b2c4..d46193a 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -2699,6 +2699,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
> struct scsi_event *evt)
>   envp[idx++] = "SDEV_MEDIA_CHANGE=1";
>   break;
>   case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
> + scsi_rescan_device(&sdev->sdev_gendev);
>   envp[idx++] = "SDEV_UA=INQUIRY_DATA_HAS_CHANGED";
>   break;
>   case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
> diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
> index 420239c..97074c9 100644
> --- a/drivers/scsi/scsi_scan.c
> +++ b/drivers/scsi/scsi_scan.c
> @@ -43,6 +43,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "scsi_priv.h"
> @@ -1524,9 +1525,14 @@ EXPORT_SYMBOL(scsi_add_device);
>  
>  void scsi_rescan_device(struct device *dev)
>  {
> + struct scsi_device *sdev = to_scsi_device(dev);
> +
>   device_lock(dev);
>  
> - scsi_attach_vpd(to_scsi_device(dev));
> + scsi_attach_vpd(sdev);
> +
> + if (sdev->handler && sdev->handler->rescan)
> + sdev->handler->rescan(sdev);
>  
>   if (dev->driver && try_module_get(dev->driver->owner)) {
>   struct scsi_driver *drv = to_scsi_driver(dev->driver);
> diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
> index 7e184c6..c7bba2b 100644
> --- a/include/scsi/scsi_dh.h
> +++ b/include/scsi/scsi_dh.h
> @@ -71,6 +71,7 @@ struct scsi_device_handler {
>   int (*activate)(struct scsi_device *, activate_complete, void *);
>   int (*prep_fn)(struct scsi_device *, struct request *);
>   int (*set_params)(struct scsi_device *, const char *);
> + void (*rescan)(struct scsi_device *);
>  };
>  
>  #ifdef CONFIG_SCSI_DH


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


Re: [PATCH 18/23] scsi_dh_alua: Send TEST UNIT READY to poll for transitioning

2016-02-11 Thread Ewan Milne
On Mon, 2016-02-08 at 15:34 +0100, Hannes Reinecke wrote:
> Sending a 'REPORT TARGET PORT GROUP' command is a costly operation,
> as the array has to gather information about all ports.
> So instead of using RTPG to poll for a status update when a port
> is in transitioning we should be sending a TEST UNIT READY, and
> wait for the sense code to report success.

Note that we may need to add a timeout on this somehow, I have
recently seen a bug report where an array stayed in the ALUA
transitioning state for an extremely long period of time.

That problem would occur with either the current or this new
ALUA code, the question is whether we want to handle it better.

-Ewan

> 
> Signed-off-by: Hannes Reinecke 
> Reviewed-by: Ewan Milne 
> Reviewed-by: Christoph Hellwig 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 38 
> ++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index de8e79e..a1db82f 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -466,6 +466,30 @@ static int alua_check_sense(struct scsi_device *sdev,
>  }
>  
>  /*
> + * alua_tur - Send a TEST UNIT READY
> + * @sdev: device to which the TEST UNIT READY command should be send
> + *
> + * Send a TEST UNIT READY to @sdev to figure out the device state
> + * Returns SCSI_DH_RETRY if the sense code is NOT READY/ALUA TRANSITIONING,
> + * SCSI_DH_OK if no error occurred, and SCSI_DH_IO otherwise.
> + */
> +static int alua_tur(struct scsi_device *sdev)
> +{
> + struct scsi_sense_hdr sense_hdr;
> + int retval;
> +
> + retval = scsi_test_unit_ready(sdev, ALUA_FAILOVER_TIMEOUT * HZ,
> +   ALUA_FAILOVER_RETRIES, &sense_hdr);
> + if (sense_hdr.sense_key == NOT_READY &&
> + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
> + return SCSI_DH_RETRY;
> + else if (retval)
> + return SCSI_DH_IO;
> + else
> + return SCSI_DH_OK;
> +}
> +
> +/*
>   * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
>   * @sdev: the device to be evaluated.
>   *
> @@ -735,8 +759,22 @@ static void alua_rtpg_work(struct work_struct *work)
>   alua_wq = kaluad_sync_wq;
>   pg->flags |= ALUA_PG_RUNNING;
>   if (pg->flags & ALUA_PG_RUN_RTPG) {
> + int state = pg->state;
> +
>   pg->flags &= ~ALUA_PG_RUN_RTPG;
>   spin_unlock_irqrestore(&pg->lock, flags);
> + if (state == TPGS_STATE_TRANSITIONING) {
> + if (alua_tur(sdev) == SCSI_DH_RETRY) {
> + spin_lock_irqsave(&pg->lock, flags);
> + pg->flags &= ~ALUA_PG_RUNNING;
> + pg->flags |= ALUA_PG_RUN_RTPG;
> + spin_unlock_irqrestore(&pg->lock, flags);
> + queue_delayed_work(alua_wq, &pg->rtpg_work,
> +pg->interval * HZ);
> + return;
> + }
> + /* Send RTPG on failure or if TUR indicates SUCCESS */
> + }
>   err = alua_rtpg(sdev, pg);
>   spin_lock_irqsave(&pg->lock, flags);
>   if (err == SCSI_DH_RETRY || pg->flags & ALUA_PG_RUN_RTPG) {


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


Re: [PATCH] block/sd: Return -EREMOTEIO when WRITE SAME and DISCARD are disabled

2016-02-04 Thread Ewan Milne
See below.

On Thu, 2016-02-04 at 01:48 -0500, Martin K. Petersen wrote:
> When a storage device rejects a WRITE SAME command we will disable write
> same functionality for the device and return -EREMOTEIO to the block
> layer. -EREMOTEIO will in turn prevent DM from retrying the I/O and/or
> failing the path.
> 
> Yiwen Jiang discovered a small race where WRITE SAME requests issued
> simultaneously would cause -EIO to be returned. This happened because
> any requests being prepared after WRITE SAME had been disabled for the
> device caused us to return BLKPREP_KILL. The latter caused the block
> layer to return -EIO upon completion.
> 
> To overcome this we introduce BLKPREP_INVALID which indicates that this
> is an invalid request for the device. blk_peek_request() is modified to
> return -EREMOTEIO in that case.
> 
> Reported-by: Yiwen Jiang 
> Suggested-by: Mike Snitzer 
> Signed-off-by: Martin K. Petersen 
> 
> ---
> 
> I contemplated making blk_peek_request() use rq->errors to decide what
> to return up the stack. However, I cringed at mixing errnos and SCSI
> midlayer status information in the same location.
> ---
>  block/blk-core.c   | 6 --
>  drivers/scsi/sd.c  | 4 ++--
>  include/linux/blkdev.h | 9 ++---
>  3 files changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/block/blk-core.c b/block/blk-core.c
> index 33e2f62d5062..ee833af2f892 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -2446,14 +2446,16 @@ struct request *blk_peek_request(struct request_queue 
> *q)
>  
>   rq = NULL;
>   break;
> - } else if (ret == BLKPREP_KILL) {
> + } else if (ret == BLKPREP_KILL || ret == BLKPREP_INVALID) {
> + int err = ret == BLKPREP_INVALID ? -EREMOTEIO : -EIO;

Maybe it's unnecessary, but I would put parenthesis around (ret == ... -EIO); 
for clarity.

> +
>   rq->cmd_flags |= REQ_QUIET;
>   /*
>* Mark this request as started so we don't trigger
>* any debug logic in the end I/O path.
>*/
>   blk_start_request(rq);
> - __blk_end_request_all(rq, -EIO);
> + __blk_end_request_all(rq, err);
>   } else {
>   printk(KERN_ERR "%s: bad return=%d\n", __func__, ret);
>   break;
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index ec163d08f6c3..6e841c6da632 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -761,7 +761,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd)
>   break;
>  
>   default:
> - ret = BLKPREP_KILL;
> + ret = BLKPREP_INVALID;
>   goto out;
>   }
>  
> @@ -839,7 +839,7 @@ static int sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
>   int ret;
>  
>   if (sdkp->device->no_write_same)
> - return BLKPREP_KILL;
> + return BLKPREP_INVALID;
>  
>   BUG_ON(bio_offset(bio) || bio_iovec(bio).bv_len != sdp->sector_size);
>  
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index c70e3588a48c..e990d181625a 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -680,9 +680,12 @@ static inline bool blk_write_same_mergeable(struct bio 
> *a, struct bio *b)
>  /*
>   * q->prep_rq_fn return values
>   */
> -#define BLKPREP_OK   0   /* serve it */
> -#define BLKPREP_KILL 1   /* fatal error, kill */
> -#define BLKPREP_DEFER2   /* leave on queue */
> +enum {
> + BLKPREP_OK, /* serve it */
> + BLKPREP_KILL,   /* fatal error, kill, return -EIO */
> + BLKPREP_INVALID,/* invalid command, kill, return -EREMOTEIO */
> + BLKPREP_DEFER,  /* leave on queue */
> +};

I would prefer that additional enum/constant values be added to the end
of the series, here you are changing the ordinal value of BLKPREP_DEFER
from 2 to 3.  Could you swap these?

>  extern unsigned long blk_max_low_pfn, blk_max_pfn;
>  

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] bnx2fc: bnx2fc_eh_abort(): fix wrong return code.

2016-02-01 Thread Ewan Milne
On Mon, 2016-02-01 at 16:08 +0100, Maurizio Lombardi wrote:
> If the link is not ready, the bnx2fc_eh_abort() function
> should return FAILED.
> 
> Signed-off-by: Maurizio Lombardi 
> ---
>  drivers/scsi/bnx2fc/bnx2fc_io.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
> index 0002caf..2230dab 100644
> --- a/drivers/scsi/bnx2fc/bnx2fc_io.c
> +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
> @@ -1104,8 +1104,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
>   struct bnx2fc_cmd *io_req;
>   struct fc_lport *lport;
>   struct bnx2fc_rport *tgt;
> - int rc = FAILED;
> -
> + int rc;
>  
>   rc = fc_block_scsi_eh(sc_cmd);
>   if (rc)
> @@ -1114,7 +1113,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
>   lport = shost_priv(sc_cmd->device->host);
>   if ((lport->state != LPORT_ST_READY) || !(lport->link_up)) {
>   printk(KERN_ERR PFX "eh_abort: link not ready\n");
> - return rc;
> + return FAILED;
>   }
>  
>   tgt = (struct bnx2fc_rport *)&rp[1];

Yes, because setting the initial setting of rc = FAILED is overwritten
by the result of fc_block_scsi_eh().

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] sd: Optimal I/O size is in bytes, not sectors

2016-01-20 Thread Ewan Milne
On Wed, 2016-01-20 at 11:01 -0500, Martin K. Petersen wrote:
> Commit ca369d51b3e1 ("block/sd: Fix device-imposed transfer length
> limits") accidentally switched optimal I/O size reporting from bytes to
> block layer sectors.
> 
> Signed-off-by: Martin K. Petersen 
> Reported-by: Christian Borntraeger 
> ---
>  drivers/scsi/sd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index 4e08d1cd704d..ec163d08f6c3 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -2893,7 +2893,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
>   sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS &&
>   sdkp->opt_xfer_blocks * sdp->sector_size >= PAGE_CACHE_SIZE)
>   rw_max = q->limits.io_opt =
> - logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
> + sdkp->opt_xfer_blocks * sdp->sector_size;
>   else
>   rw_max = BLK_DEF_MAX_SECTORS;
>  

Reviewed-by: Ewan D. Milne 


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


Re: scsi-debug regression with 4.5-rc?

2016-01-20 Thread Ewan Milne
So I have a report from our test people that the optimal_io_size sysfs
value is now different by a factor of 512 from what it used to be...

>Here is what is executed:
>
>modprobe scsi_debug dev_size_mb=32 sector_size=4096 opt_blks=64
>num_tgts=1
>
>And here is what our test is capturing:
>
>/sys/dev/block/8:0/queue/optimal_io_size = 512 differs from expected
>value 
>1048576!
>
>
>(So with 64 it's 512,  with opt_blks=256 it's 2048,  but it used to be
>1048576)

This looks like it might be due to commit:

commit ca369d51b3e1649be4a72addd6d6a168cfb3f537
Author: Martin K. Petersen 
Date:   Fri Nov 13 16:46:48 2015 -0500

block/sd: Fix device-imposed transfer length limits

It would appear that this commit has changed the meaning of
the queue limits io_opt field to be 512-byte normalized
sectors instead of bytes.  Parts of the diff:

-   blk_queue_io_opt(sdkp->disk->queue,
-get_unaligned_be32(&buffer[12]) * sector_sz);

...

+   sdkp->opt_xfer_blocks = get_unaligned_be32(&buffer[12]);

...

+   if (sdkp->opt_xfer_blocks && sdkp->opt_xfer_blocks <= dev_max &&
+   sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS)
+   rw_max = q->limits.io_opt =
+   logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
+   else
+   rw_max = BLK_DEF_MAX_SECTORS;


---

Was this intentional?  I would have thought we would not want to change
the usermode meaning of this field.

-Ewan


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


Re: [PATCH 3/3] block: Export max_dev_sectors_kb in sysfs

2015-12-17 Thread Ewan Milne
On Wed, 2015-12-16 at 17:53 -0500, Martin K. Petersen wrote:
> Some storage devices report a maximum transfer length which indicates
> the maximum size of an I/O request that the device can process. This
> limit is enforced in combination with the controller's max_hw_sectors
> and DMA constraints to ensure that we do not issue a command too big for
> the device.
> 
> Export the max_dev_sectors_kb queue limit in sysfs and update the
> documentation accordingly.
> 
> Signed-off-by: Martin K. Petersen 
> ---
>  Documentation/ABI/testing/sysfs-block |  9 +
>  Documentation/block/queue-sysfs.txt   | 11 +--
>  block/blk-settings.c  |  4 +++-
>  block/blk-sysfs.c | 13 +
>  4 files changed, 34 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-block 
> b/Documentation/ABI/testing/sysfs-block
> index 71d184dbb70d..4f284d38c085 100644
> --- a/Documentation/ABI/testing/sysfs-block
> +++ b/Documentation/ABI/testing/sysfs-block
> @@ -235,3 +235,12 @@ Description:
>   write_same_max_bytes is 0, write same is not supported
>   by the device.
>  
> +What:/sys/block//queue/max_dev_sectors_kb
> +Date:December 2015
> +Contact: Martin K. Petersen 
> +Description:
> + Some storage devices report the maximum size that the
> + device can process in a single READ or WRITE
> + request. This limit is used in combination with
> + constraints set by the controller driver to limit the
> + size of filesystem requests.
> diff --git a/Documentation/block/queue-sysfs.txt 
> b/Documentation/block/queue-sysfs.txt
> index e5d914845be6..a078995f3eae 100644
> --- a/Documentation/block/queue-sysfs.txt
> +++ b/Documentation/block/queue-sysfs.txt
> @@ -55,9 +55,15 @@ logical_block_size (RO)
>  ---
>  This is the logcal block size of the device, in bytes.
>  
> +max_dev_sectors_kb (R)
> +--
> +This is the maximum number of kilobytes supported by the storage device
> +for a READ or WRITE request.
> +
>  max_hw_sectors_kb (RO)
>  --
> -This is the maximum number of kilobytes supported in a single data transfer.
> +This is the maximum number of kilobytes supported by the storage
> +controller in a single data transfer.
>  
>  max_integrity_segments (RO)
>  ---
> @@ -68,7 +74,8 @@ max_sectors_kb (RW)
>  ---
>  This is the maximum number of kilobytes that the block layer will allow
>  for a filesystem request. Must be smaller than or equal to the maximum
> -size allowed by the hardware.
> +size allowed by the storage controller (max_hw_sectors_kb) and the
> +maximum size allowed by the storage device (max_dev_sectors_kb).
>  
>  max_segments (RO)
>  -
> diff --git a/block/blk-settings.c b/block/blk-settings.c
> index dd4973583978..362b0179c86a 100644
> --- a/block/blk-settings.c
> +++ b/block/blk-settings.c
> @@ -232,7 +232,9 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
>   *max_sectors is a soft limit imposed by the block layer for
>   *filesystem type requests.  This value can be overridden on a
>   *per-device basis in /sys/block//queue/max_sectors_kb.
> - *The soft limit can not exceed max_hw_sectors.
> + *
> + *The soft limit's lower bound is the page cache size and it can not
> + *exceed neither max_hw_sectors, nor max_dev_sectors.
>   **/
>  void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int 
> max_hw_sectors)
>  {
> diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
> index e140cc487ce1..c289f9f6dcd9 100644
> --- a/block/blk-sysfs.c
> +++ b/block/blk-sysfs.c
> @@ -225,6 +225,13 @@ static ssize_t queue_max_hw_sectors_show(struct 
> request_queue *q, char *page)
>   return queue_var_show(max_hw_sectors_kb, (page));
>  }
>  
> +static ssize_t queue_max_dev_sectors_show(struct request_queue *q, char 
> *page)
> +{
> + int max_dev_sectors_kb = q->limits.max_dev_sectors >> 1;

Consider adding inline queue_max_dev_sectors() to blkdev.h and using it
in the line above?

> +
> + return queue_var_show(max_dev_sectors_kb, (page));
> +}
> +
>  #define QUEUE_SYSFS_BIT_FNS(name, flag, neg) \
>  static ssize_t   
> \
>  queue_show_##name(struct request_queue *q, char *page)   
> \
> @@ -371,6 +378,11 @@ static struct queue_sysfs_entry 
> queue_max_hw_sectors_entry = {
>   .show = queue_max_hw_sectors_show,
>  };
>  
> +static struct queue_sysfs_entry queue_max_dev_sectors_entry = {
> + .attr = {.name = "max_dev_sectors_kb", .mode = S_IRUGO },
> + .show = queue_max_dev_sectors_show,
> +};
> +
>  static struct queue_sysfs_entry queue_max_segments_entry = {
>   .attr = {.name = "max_segments", .mode = S_IRUGO },
>   .show = queue_max_segments_show,
> @@ -483,6 +495,7 @@

Re: [PATCH 2/3] sd: Reject optimal transfer length smaller than page size

2015-12-17 Thread Ewan Milne
On Wed, 2015-12-16 at 17:53 -0500, Martin K. Petersen wrote:
> Eryu Guan reported that loading scsi_debug would fail. This turned out
> to be caused by scsi_debug reporting an optimal I/O size of 32KB which
> is smaller than the 64KB page size on the PowerPC system in question.
> 
> Add a check to ensure that we only use the device-reported OPTIMAL
> TRANSFER LENGTH if it is bigger than or equal to the page cache size.
> 
> Reported-by: Eryu Guan 
> Reported-by: Ming Lei 
> Signed-off-by: Martin K. Petersen 
> ---
>  drivers/scsi/sd.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index 3d22fc3e3c1a..4e08d1cd704d 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -2885,10 +2885,13 @@ static int sd_revalidate_disk(struct gendisk *disk)
>  
>   /*
>* Use the device's preferred I/O size for reads and writes
> -  * unless the reported value is unreasonably large (or garbage).
> +  * unless the reported value is unreasonably small, large, or
> +  * garbage.
>*/
> - if (sdkp->opt_xfer_blocks && sdkp->opt_xfer_blocks <= dev_max &&
> - sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS)
> + if (sdkp->opt_xfer_blocks &&
> + sdkp->opt_xfer_blocks <= dev_max &&
> + sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS &&
> + sdkp->opt_xfer_blocks * sdp->sector_size >= PAGE_CACHE_SIZE)
>   rw_max = q->limits.io_opt =
>   logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
>   else

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 1/3] scsi_debug: Increase the reported optimal transfer length

2015-12-17 Thread Ewan Milne
On Wed, 2015-12-16 at 17:53 -0500, Martin K. Petersen wrote:
> The OPTIMAL TRANSFER LENGTH reported by scsi_debug is 64 blocks which
> translates to 32KB with the default logical block size. That's much
> lower than what real storage devices typically report (256KB to 1MB).
> 
> Bump the optimal transfer length to 1024 blocks.
> 
> Signed-off-by: Martin K. Petersen 
> ---
>  drivers/scsi/scsi_debug.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index d09d60293c27..b80b037f2982 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -129,7 +129,7 @@ static const char *scsi_debug_version_date = "20141022";
>  #define DEF_NO_LUN_0   0
>  #define DEF_NUM_PARTS   0
>  #define DEF_OPTS   0
> -#define DEF_OPT_BLKS 64
> +#define DEF_OPT_BLKS 1024
>  #define DEF_PHYSBLK_EXP 0
>  #define DEF_PTYPE   0
>  #define DEF_REMOVABLE false
> @@ -4140,7 +4140,7 @@ MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> 
> have lun 0)");
>  MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))");
>  MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
>  MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)");
> -MODULE_PARM_DESC(opt_blks, "optimal transfer length in block (def=64)");
> +MODULE_PARM_DESC(opt_blks, "optimal transfer length in blocks (def=1024)");
>  MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 
> 8->recovered_err... (def=0)");
>  MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)");
>  MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");

Reviewed-by: Ewan D. Milne 


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


Re: [PATCHv4 1/1] SCSI: hosts: update to use ida_simple for host_no management

2015-12-14 Thread Ewan Milne
On Sun, 2015-12-13 at 11:16 -0800, Lee Duncan wrote:
> On 12/11/2015 07:31 AM, Ewan Milne wrote:
> > On Thu, 2015-12-10 at 13:48 -0800, Lee Duncan wrote:
> >> On 11/17/2015 03:20 PM, Martin K. Petersen wrote:
> >>>>>>>> "Lee" == Lee Duncan  writes:
> >>>
> >>> Lee> Martin: I will be glad to update the patch, creating a modprobe
> >>> Lee> parameter as suggested, if you find this acceptable.
> >>>
> >>> For development use a module parameter would be fine. But I am concerned
> >>> about our support folks that rely on the incrementing host number when
> >>> analyzing customer log files.
> >>>
> >>> Ewan: How do you folks feel about this change?
> >>>
> >>
> >> Ewan?
> > 
> > 
> > Personally, I think having host numbers that increase essentially
> > without limit (I think I've seen this with iSCSI sessions) are a
> > problem, the numbers start to lose meaning for people when they
> > are not easily recognizable.  Yes, it can help when you're analyzing
> > a log file, but it seems to me that you would want to track the
> > host state throughout anyway, so you could just follow the number
> > as it changes.
> > 
> > If we change the behavior, we have to change documentation, and
> > our support people will get calls.  But that's not a reason not
> > to do it.
> > 
> > -Ewan
> > 
> 
> Ewan:
> 
> Thank you for your reply. I agree with you, which is why I generated
> this patch.
> 
> If we *do* make this change, do you think it would be useful to have a
> module option to revert to the old numbering behavior? I actually think
> it would be more confusing to support two behaviors than it would be to
> bite the bullet (so to speak) and make the change.
> 

I'm not opposed to having the module option if others (Martin?) feel
they need it, but generally I think it's better to keep things as simple
as possible.  So, unless there are strong objections, I would say no.

-Ewan



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


Re: [PATCHv4 1/1] SCSI: hosts: update to use ida_simple for host_no management

2015-12-11 Thread Ewan Milne
On Thu, 2015-12-10 at 13:48 -0800, Lee Duncan wrote:
> On 11/17/2015 03:20 PM, Martin K. Petersen wrote:
> >> "Lee" == Lee Duncan  writes:
> > 
> > Lee> Martin: I will be glad to update the patch, creating a modprobe
> > Lee> parameter as suggested, if you find this acceptable.
> > 
> > For development use a module parameter would be fine. But I am concerned
> > about our support folks that rely on the incrementing host number when
> > analyzing customer log files.
> > 
> > Ewan: How do you folks feel about this change?
> > 
> 
> Ewan?


Personally, I think having host numbers that increase essentially
without limit (I think I've seen this with iSCSI sessions) are a
problem, the numbers start to lose meaning for people when they
are not easily recognizable.  Yes, it can help when you're analyzing
a log file, but it seems to me that you would want to track the
host state throughout anyway, so you could just follow the number
as it changes.

If we change the behavior, we have to change documentation, and
our support people will get calls.  But that's not a reason not
to do it.

-Ewan


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


Re: [PATCH] ses: Fix problems with simple enclosures

2015-12-08 Thread Ewan Milne
On Tue, 2015-12-08 at 09:00 -0800, James Bottomley wrote:
> Simple enclosure implementations (mostly USB) are allowed to return only
> page 8 to every diagnostic query.  That really confuses our
> implementation because we assume the return is the page we asked for and
> end up doing incorrect offsets based on bogus information leading to
> accesses outside of allocated ranges.  Fix that by checking the page
> code of the return and giving an error if it isn't the one we asked for.
> This should fix reported bugs with USB storage by simply refusing to
> attach to enclosures that behave like this.  It's also good defensive
> practise now that we're starting to see more USB enclosures.
> 
> Reported-by: Andrea Gelmini 
> Cc: sta...@vger.kernel.org
> Signed-off-by: James Bottomley 
> 
> ---
> 
> diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
> index dcb0d76..7d9cec5 100644
> --- a/drivers/scsi/ses.c
> +++ b/drivers/scsi/ses.c
> @@ -84,6 +84,7 @@ static void init_device_slot_control(unsigned char 
> *dest_desc,
>  static int ses_recv_diag(struct scsi_device *sdev, int page_code,
>void *buf, int bufflen)
>  {
> + int ret;
>   unsigned char cmd[] = {
>   RECEIVE_DIAGNOSTIC,
>   1,  /* Set PCV bit */
> @@ -92,9 +93,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int 
> page_code,
>   bufflen & 0xff,
>   0
>   };
> + unsigned char recv_page_code;
>  
> - return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
> + ret =  scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
>   NULL, SES_TIMEOUT, SES_RETRIES, NULL);
> + if (unlikely(!ret))
> + return ret;
> +
> + recv_page_code = ((unsigned char *)buf)[0];
> +
> + if (likely(recv_page_code == page_code))
> + return ret;
> +
> + /* successful diagnostic but wrong page code.  This happens to some
> +  * USB devices, just print a message and pretend there was an error */
> +
> + sdev_printk(KERN_ERR, sdev,
> + "Wrong diagnostic page; asked for %d got %u\n",
> + page_code, recv_page_code);
> +
> + return -EINVAL;
>  }
>  
>  static int ses_send_diag(struct scsi_device *sdev, int page_code,
> 
> 

Reviewed-by: Ewan D. Milne 


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


Re: BUG: KASAN: slab-out-of-bounds in ses_enclosure_data_process+0x900/0xe50

2015-12-04 Thread Ewan Milne
On Fri, 2015-12-04 at 11:16 -0800, James Bottomley wrote:
> On Fri, 2015-12-04 at 11:58 -0500, Ewan Milne wrote:
> > On Thu, 2015-12-03 at 23:20 +0100, Andrea Gelmini wrote:
> > > On Thu, Dec 03, 2015 at 12:59:06PM -0800, James Bottomley wrote:
> > > > sg_map -i
> > > > 
> > > > in your system, you should see something with an inquiry string like
> > > > enclosure.  It's the /dev/sg of that you need to run sg_ses on.
> > > 
> > > root@glen:/home/gelma# sg_map -i
> > > /dev/sg0  /dev/sda  ATA   Samsung SSD 850   1B6Q
> > > /dev/sg1  /dev/sr0  HL-DT-ST  DVDRAM GU40N  QX23
> > > /dev/sg2  /dev/sdb  WDMy Passport 0820  1007
> > > /dev/sg3  WDSES Device1007
> > > 
> > > And following Douglas' instructions:
> > > 
> > > root@glen:/home/gelma# lsscsi -gs
> > > [0:0:0:0]diskATA  Samsung SSD 850  1B6Q  /dev/sda   /dev/sg0  
> > >  1.02TB
> > > [1:0:0:0]cd/dvd  HL-DT-ST DVDRAM GU40N QX23  /dev/sr0   /dev/sg1  
> > >   -
> > > [8:0:0:0]diskWD   My Passport 0820 1007  /dev/sdb   /dev/sg2  
> > >  2.00TB
> > > [8:0:0:1]enclosu WD   SES Device   1007  -  /dev/sg3  
> > >  
> > > 
> > > root@glen:/home/gelma# sg_ses /dev/sg3
> > >   WDSES Device1007
> > > Supported diagnostic pages:
> > >   Supported Diagnostic Pages [sdp] [0x0]
> > >   Short Enclosure Status (SES) [ses] [0x8]
> > >[0x80]
> > >[0x83]
> > >[0x84]
> > >[0x85]
> > > 
> > > 
> > > Well, if it's better for you, I can give you root access to a machine 
> > > with this device
> > > connected to.
> > > 
> > > Thanks a lot for your time,
> > > Andrea
> > 
> > There seems to be a problem with the ses code if the device only reports
> > Short Enclosure Status.  We probably need to do something like:
> > 
> > diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
> > index eba183c..065a528 100644
> > --- a/drivers/scsi/ses.c
> > +++ b/drivers/scsi/ses.c
> > @@ -537,6 +537,15 @@ static int ses_intf_add(struct device *cdev,
> > if (result)
> > goto recv_failed;
> >  
> > +   /* If enclosure only supports Short Enclosure Status page (08),
> > +* it returns that page regardless of what we requested, and
> > +* only returns vendor-specific status.  There is nothing wrong
> > +* with such enclosures, we just can't make use of them. */
> > +   if (hdr_buf[0] == 8) {
> > +   err = -ENODEV;
> > +   goto err_init_free_nomsg;
> > +   }
> > +
> > len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
> > buf = kzalloc(len, GFP_KERNEL);
> > if (!buf)
> > @@ -646,9 +655,10 @@ static int ses_intf_add(struct device *cdev,
> > kfree(ses_dev->page2);
> > kfree(ses_dev->page1);
> >   err_init_free:
> > +   sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n",
> > err);
> > + err_init_free_nomsg:
> > kfree(ses_dev);
> > kfree(hdr_buf);
> > -   sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n",
> > err);
> > return err;
> >  }
> > 
> > Otherwise we go off issuing commands for pages the device says it won't
> > return.  I don't see offhand how this would cause KASAN errors though.
> 
> I think we have two separate bugs.  One is the usual USB devices getting
> into a new SCSI standard and getting it wrong.  The other looks to be an
> enumeration problem ... possibly because ses2 added an indexed
> descriptor which current SES doesn't cope with.
> 
> Anyway, in concentrating on the USB problem first, I think we need to
> code a little more defensively, like this.

This could certainly be the case for a USB device, however I have also
had a report of this for regular SCSI attached devices with EncServ=1
that only supported Short Enclosure Status.  The SES-3 spec 4.3.3 says
that in this case, it "...shall always return the Short Enclosure
Status diagnostic page, regardless of which SES diagnostic page is
requested..."  The person who reported the problem wanted to have the
error messages removed about all his spec-compliant devices.

Short Enclosure Status appears to be vendor-specific, it doesn't look
like we can do anything with it.

But anyway, there's still the other problem...

-Ew

Re: BUG: KASAN: slab-out-of-bounds in ses_enclosure_data_process+0x900/0xe50

2015-12-04 Thread Ewan Milne
On Thu, 2015-12-03 at 23:20 +0100, Andrea Gelmini wrote:
> On Thu, Dec 03, 2015 at 12:59:06PM -0800, James Bottomley wrote:
> > sg_map -i
> > 
> > in your system, you should see something with an inquiry string like
> > enclosure.  It's the /dev/sg of that you need to run sg_ses on.
> 
> root@glen:/home/gelma# sg_map -i
> /dev/sg0  /dev/sda  ATA   Samsung SSD 850   1B6Q
> /dev/sg1  /dev/sr0  HL-DT-ST  DVDRAM GU40N  QX23
> /dev/sg2  /dev/sdb  WDMy Passport 0820  1007
> /dev/sg3  WDSES Device1007
> 
> And following Douglas' instructions:
> 
> root@glen:/home/gelma# lsscsi -gs
> [0:0:0:0]diskATA  Samsung SSD 850  1B6Q  /dev/sda   /dev/sg0   
> 1.02TB
> [1:0:0:0]cd/dvd  HL-DT-ST DVDRAM GU40N QX23  /dev/sr0   /dev/sg1  
>   -
> [8:0:0:0]diskWD   My Passport 0820 1007  /dev/sdb   /dev/sg2   
> 2.00TB
> [8:0:0:1]enclosu WD   SES Device   1007  -  /dev/sg3  
>  
> 
> root@glen:/home/gelma# sg_ses /dev/sg3
>   WDSES Device1007
> Supported diagnostic pages:
>   Supported Diagnostic Pages [sdp] [0x0]
>   Short Enclosure Status (SES) [ses] [0x8]
>[0x80]
>[0x83]
>[0x84]
>[0x85]
> 
> 
> Well, if it's better for you, I can give you root access to a machine with 
> this device
> connected to.
> 
> Thanks a lot for your time,
> Andrea

There seems to be a problem with the ses code if the device only reports
Short Enclosure Status.  We probably need to do something like:

diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index eba183c..065a528 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -537,6 +537,15 @@ static int ses_intf_add(struct device *cdev,
if (result)
goto recv_failed;
 
+   /* If enclosure only supports Short Enclosure Status page (08),
+* it returns that page regardless of what we requested, and
+* only returns vendor-specific status.  There is nothing wrong
+* with such enclosures, we just can't make use of them. */
+   if (hdr_buf[0] == 8) {
+   err = -ENODEV;
+   goto err_init_free_nomsg;
+   }
+
len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
buf = kzalloc(len, GFP_KERNEL);
if (!buf)
@@ -646,9 +655,10 @@ static int ses_intf_add(struct device *cdev,
kfree(ses_dev->page2);
kfree(ses_dev->page1);
  err_init_free:
+   sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n",
err);
+ err_init_free_nomsg:
kfree(ses_dev);
kfree(hdr_buf);
-   sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n",
err);
return err;
 }

Otherwise we go off issuing commands for pages the device says it won't
return.  I don't see offhand how this would cause KASAN errors though.

-Ewan


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


Re: [PATCH v1 1/1] scsi_debug: check for bigger value first

2015-11-30 Thread Ewan Milne
On Thu, 2015-11-26 at 20:22 +0200, Andy Shevchenko wrote:
> From: Andy Shevchenko 
> 
> Even for signed types we have to check for bigger positive value first.
> Otherwise it will be never happened.
> 
> Acked-by: Douglas Gilbert 
> Signed-off-by: Andy Shevchenko 
> ---
>  drivers/scsi/scsi_debug.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index dfcc45b..f773b34 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -4846,10 +4846,10 @@ static int __init scsi_debug_init(void)
>   /* play around with geometry, don't waste too much on track 0 */
>   sdebug_heads = 8;
>   sdebug_sectors_per = 32;
> - if (scsi_debug_dev_size_mb >= 16)
> - sdebug_heads = 32;
> - else if (scsi_debug_dev_size_mb >= 256)
> + if (scsi_debug_dev_size_mb >= 256)
>   sdebug_heads = 64;
> + else if (scsi_debug_dev_size_mb >= 16)
> + sdebug_heads = 32;
>   sdebug_cylinders_per = (unsigned long)sdebug_capacity /
>  (sdebug_sectors_per * sdebug_heads);
>   if (sdebug_cylinders_per >= 1024) {

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH RESEND] scsi_debug: fix prevent_allow+verify regressions

2015-11-24 Thread Ewan Milne
On Sun, 2015-11-22 at 12:11 -0500, Douglas Gilbert wrote:
> Ruediger Meier observed a regression with the PREVENT ALLOW
> MEDIUM REMOVAL command in lk 3.19:
>http://www.spinics.net/lists/util-linux-ng/msg11448.html
> 
> Inspection indicated the same regression with VERIFY(10).
> 
> The patch is against lk 3.19.3 and also works with lk 4.3.0 .
> With this patch both commands are accepted and do nothing.
> 
> ChangeLog:
>- fix the lk 3.19 regression so that the PREVENT ALLOW
>  MEDIUM REMOVAL command is supported once again
>- same fix for VERIFY(10)
> 
> Signed-off-by: Douglas Gilbert 

Reviewed-by: Ewan D. Milne 


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


Re: kernel BUG at drivers/scsi/scsi_lib.c:1096!

2015-11-20 Thread Ewan Milne
On Fri, 2015-11-20 at 15:55 +0100, Hannes Reinecke wrote:
> Can't we have a joint effort here?
> I've been spending a _LOT_ of time trying to debug things here, but
> none of the ideas I've come up with have been able to fix anything.

Yes.  I'm not the one primarily looking at it, and we don't have a
reproducer in-house.  We just have the one dump right now.

> 
> I'm almost tempted to increase the count from scsi_alloc_sgtable()
> by one and be done with ...
> 

That might not fix it if it is a problem with the merge code, though.


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


Re: kernel BUG at drivers/scsi/scsi_lib.c:1096!

2015-11-20 Thread Ewan Milne
On Thu, 2015-11-19 at 16:35 +0100, Hannes Reinecke wrote:
> On 11/19/2015 09:23 AM, Christoph Hellwig wrote:
> > It's pretty much guaranteed a block layer bug, most likely in the
> > merge bios to request infrastucture where we don't obey the merging
> > limits properly.
> > 
> > Does either of you have a known good and first known bad kernel?
> 
> Well, I have been fighting a similar issue for several months now,
> albeit with multipath enabled. Haven't had much progress with this,
> sadly.
> Seeing that this is our distro kernel it might or might not be
> related; however, as the symptoms are identical there still is a
> chance that this is actually a generic block-layer problem.
> 
> Cheers,
> 
> Hannes

We have seen this also.  (e.g.  req->nr_phys_segments was 3, but
blk_rq_map_sg() returned 4.)  I was suspicious of the patch:

bio: modify __bio_add_page() to accept pages that don't start a new segment

But we put some debugging code in and didn't hit it.  We haven't
found the problem yet, either, though.  We're still looking.

As Christoph said, it would seem to be a problem with the block layer
merging.

The API for this seems defective, in that blk_rq_map_sg() should
never be returning a value indicating that it overwrote past the
end of the supplied SG array and depend on the caller to check it.
(We could get data corruption on another I/O if it used adjacent
memory for a different SG list, for example.)

-Ewan





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


Re: [PATCH] [SCSI] st: Remove obsolete scsi_tape.max_pfn

2015-11-17 Thread Ewan Milne
On Sun, 2015-11-15 at 12:48 +0100, Geert Uytterhoeven wrote:
> Its last user was removed 10 years ago, in commit
> 8b05b773b6030de5 ("[SCSI] convert st to use scsi_execute_async").
> 
> Signed-off-by: Geert Uytterhoeven 
> ---
>  drivers/scsi/st.h | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
> index b6486b5d86811227..8c732c8de0153eb1 100644
> --- a/drivers/scsi/st.h
> +++ b/drivers/scsi/st.h
> @@ -148,8 +148,6 @@ struct scsi_tape {
>   int tape_type;
>   int long_timeout;   /* timeout for commands known to take long time 
> */
>  
> - unsigned long max_pfn;  /* the maximum page number reachable by the HBA 
> */
> -
>   /* Mode characteristics */
>   struct st_modedef modes[ST_NBR_MODES];
>   int current_mode;

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] scsi_sysfs: Fix queue_ramp_up_period return code

2015-10-27 Thread Ewan Milne
On Mon, 2015-10-26 at 15:54 +0100, Peter Oberparleiter wrote:
> Writing a number to /sys/bus/scsi/devices//queue_ramp_up_period
> returns the value of that number instead of the number of bytes written.
> This behavior can confuse programs expecting POSIX write() semantics.
> Fix this by returning the number of bytes written instead.
> 
> Signed-off-by: Peter Oberparleiter 
> ---
>  drivers/scsi/scsi_sysfs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
> index b89..6b0f292 100644
> --- a/drivers/scsi/scsi_sysfs.c
> +++ b/drivers/scsi/scsi_sysfs.c
> @@ -898,7 +898,7 @@ sdev_store_queue_ramp_up_period(struct device *dev,
>   return -EINVAL;
> 
>   sdev->queue_ramp_up_period = msecs_to_jiffies(period);
> - return period;
> + return count;
>  }
> 
>  static DEVICE_ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 0/3] SCSI: Fix hard lockup in scsi_remove_target()

2015-10-14 Thread Ewan Milne
On Wed, 2015-10-14 at 07:30 -0700, James Bottomley wrote:
> On Wed, 2015-10-14 at 15:50 +0200, Johannes Thumshirn wrote:
> > Removing a SCSI target via scsi_remove_target() suspected to be racy. When a
> > sibling get's removed from the list it can occassionly happen that one CPU 
> > is
> > stuck endlessly looping around this code block
> > 
> > list_for_each_entry(starget, &shost->__targets, siblings) {
> > if (starget->state == STARGET_DEL)
> > continue;
> 
> How long is the __targets list?  It seems a bit unlikely that this is
> the exact cause, because for a short list all in STARGET_DEL that loop
> should exit very quickly.  Where in the code does scsi_remove_target
> +0x68/0x240 actually point to?
> 
> Is it not a bit more likely that we're following a removed list element?
> Since that points back to itself, the list_for_each_entry() would then
> circulate forever.  If that's the case the simple fix would be to use
> the safe version of the list traversal macro.
> 
> James

For what it's worth, I've seen a dump where this was exactly the case.
starget was in STARGET_DEL state, starget->siblings pointed to itself,
kref was 0, reap_ref was 0 (this was a while back).

The problem was not able to be reproduced at the time.

-Ewan


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


Re: [PATCH 19/23] scsi_dh_alua: Use workqueue for RTPG

2015-09-23 Thread Ewan Milne
On Tue, 2015-09-22 at 22:15 +0200, Hannes Reinecke wrote:
> On 09/22/2015 09:49 PM, Ewan Milne wrote:
> > On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> >> The current ALUA device_handler has two drawbacks:
> >> - We're sending a 'SET TARGET PORT GROUP' command to every LUN,
> >>   disregarding the fact that several LUNs might be in a port group
> >>   and will be automatically switched whenever _any_ LUN within
> >>   that port group receives the command.
> >> - Whenever a LUN is in 'transitioning' mode we cannot block I/O
> >>   to that LUN, instead the controller has to abort the command.
> >>   This leads to increased traffic across the wire and heavy load
> >>   on the controller during switchover.
> > 
> > I'm not sure I understand what this means - why couldn't we block I/O?
> > and what does 'heavy load' mean?  Aborting commands is 'heavy load'?
> > 
> If we're getting a sense code indicating that the LUN is in
> transitioning _and_ we're blocking I/O we never ever send down I/Os to
> that driver anymore, so we cannot receive any sense codes indicating the
> transitioning is done.
> At the same time, every I/O we're sending down will be returned by the
> storage I/O with a sense code, requiring us to retry the command.
> Hence we're constantly retrying I/O.

Ah, OK.  Perhaps including this explanation either in the comments with
patch 22/23 which adds the TEST UNIT READY commands to poll for the
status, or in the patch description somewhere would be helpful.

> 
> [ .. ]
> >> @@ -811,10 +1088,17 @@ failed:
> >>  static void alua_bus_detach(struct scsi_device *sdev)
> >>  {
> >>struct alua_dh_data *h = sdev->handler_data;
> >> +  struct alua_port_group *pg;
> >>  
> >> -  if (h->pg) {
> >> -  kref_put(&h->pg->kref, release_port_group);
> >> -  h->pg = NULL;
> >> +  spin_lock(&h->pg_lock);
> >> +  pg = h->pg;
> >> +  rcu_assign_pointer(h->pg, NULL);
> >> +  spin_unlock(&h->pg_lock);
> >> +  synchronize_rcu();
> >> +  if (pg) {
> >> +  if (pg->rtpg_sdev)
> >> +  flush_workqueue(pg->work_q);
> >> +  kref_put(&pg->kref, release_port_group);
> >>}
> >>sdev->handler_data = NULL;
> >>kfree(h);
> > 
> > So, you've already had a bit of discussion with Christoph about this,
> > the main portion of your ALUA rewrite, and I won't go over all of that,
> > except to say that I'd have to agree that having separate work queues
> > for the different RTPG/STPG functions and having them manipulate each
> > other's flags seems like we'd be better off having just one work
> > function that did everything.  Less messy and easier to maintain.
> > 
> > Also, it seems like wrong ordering of kref_get() vs. scsi_device_get(),
> > in alua_rtpg_queue() since they are released as kref_put() then
> > scsi_device_put()?
> > 
> Yeah, I've reworked the reference counting.
> And reverted the workqueue handling to use the original model.
> 
> Cheers,
> 
> Hannes


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


Re: [PATCH 23/23] scsi_dh_alua: Update version to 2.0

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 3c6b365..5b15936 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -31,7 +31,7 @@
>  #include 
>  
>  #define ALUA_DH_NAME "alua"
> -#define ALUA_DH_VER "1.3"
> +#define ALUA_DH_VER "2.0"
>  
>  #define TPGS_STATE_OPTIMIZED 0x0
>  #define TPGS_STATE_NONOPTIMIZED  0x1

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 22/23] scsi_dh_alua: Send TEST UNIT READY to poll for transitioning

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Sending a 'REPORT TARGET PORT GROUP' command is a costly operation,
> as the array has to gather information about all ports.
> So instead of using RTPG to poll for a status update when a port
> is in transitioning we should be sending a TEST UNIT READY, and
> wait for the sense code to report success.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 33 
> ++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 2fa985e..3c6b365 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -467,6 +467,30 @@ static int alua_check_sense(struct scsi_device *sdev,
>  }
>  
>  /*
> + * alua_tur - Send a TEST UNIT READY
> + * @sdev: device to which the TEST UNIT READY command should be send
> + *
> + * Send a TEST UNIT READY to @sdev to figure out the device state
> + * Returns SCSI_DH_RETRY if the sense code is NOT READY/ALUA TRANSITIONING,
> + * SCSI_DH_OK if no error occured, and SCSI_DH_IO otherwise.
> + */
> +static int alua_tur(struct scsi_device *sdev)
> +{
> + struct scsi_sense_hdr sense_hdr;
> + int retval;
> +
> + retval = scsi_test_unit_ready(sdev, ALUA_FAILOVER_TIMEOUT * HZ,
> +   ALUA_FAILOVER_RETRIES, &sense_hdr);
> + if (sense_hdr.sense_key == NOT_READY &&
> + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a)
> + return SCSI_DH_RETRY;
> + else if (retval)
> + return SCSI_DH_IO;
> + else
> + return SCSI_DH_OK;
> +}
> +
> +/*
>   * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
>   * @sdev: the device to be evaluated.
>   *
> @@ -725,7 +749,16 @@ static void alua_rtpg_work(struct work_struct *work)
>   return;
>   }
>   if (pg->flags & ALUA_PG_RUN_RTPG) {
> + int state = pg->state;
>   spin_unlock_irqrestore(&pg->rtpg_lock, flags);
> + if (state == TPGS_STATE_TRANSITIONING) {
> + if (alua_tur(sdev) == SCSI_DH_RETRY) {
> + queue_delayed_work(pg->work_q, &pg->rtpg_work,
> +pg->interval * HZ);
> + return;
> + }
> + /* Send RTPG on failure or if TUR indicates SUCCESS */
> + }
>   err = alua_rtpg(sdev, pg);
>   if (err == SCSI_DH_RETRY) {
>   queue_delayed_work(pg->work_q, &pg->rtpg_work,

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 21/23] scsi_dh_alua: update all port states

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> When we read in the target port group state we should be
> updating all affected port groups, otherwise we risk
> running out of sync.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 21 +
>  1 file changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 8717fd3..2fa985e 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -477,11 +477,13 @@ static int alua_check_sense(struct scsi_device *sdev,
>  static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
>  {
>   struct scsi_sense_hdr sense_hdr;
> + struct alua_port_group *tmp_pg;
>   int len, k, off, valid_states = 0, bufflen = ALUA_RTPG_SIZE;
>   unsigned char *ucp, *buff;
>   unsigned err, retval;
>   unsigned int tpg_desc_tbl_off;
>   unsigned char orig_transition_tmo;
> + unsigned long flags;
>  
>   if (!pg->expiry) {
>   if (!pg->transition_tmo)
> @@ -584,17 +586,28 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg)
>   else
>   tpg_desc_tbl_off = 4;
>  
> + spin_lock_irqsave(&port_group_lock, flags);
>   for (k = tpg_desc_tbl_off, ucp = buff + tpg_desc_tbl_off;
>k < len;
>k += off, ucp += off) {

"ucp" is not really a good variable name, it matches nothing in the T10
spec.  The structure is a "Target Port Group Descriptor".  I realize it
was already there, but maybe this is a good opportunity to change it?

>  
> - if (pg->group_id == get_unaligned_be16(&ucp[2])) {
> - pg->state = ucp[0] & 0x0f;
> - pg->pref = ucp[0] >> 7;
> - valid_states = ucp[1];
> + list_for_each_entry(tmp_pg, &port_group_list, node) {
> + u16 group_id = get_unaligned_be16(&ucp[2]);

This is invariant and should be outside the loop.

> + if (tmp_pg->group_id != group_id)
> + continue;
> + if (tmp_pg->device_id_size != pg->device_id_size)
> + continue;
> + if (strncmp(tmp_pg->device_id_str, pg->device_id_str,
> + tmp_pg->device_id_size))
> + continue;
> + tmp_pg->state = ucp[0] & 0x0f;
> + tmp_pg->pref = ucp[0] >> 7;
> + if (tmp_pg == pg)
> + valid_states = ucp[1];
>   }
>   off = 8 + (ucp[7] * 4);
>   }
> + spin_unlock_irqrestore(&port_group_lock, flags);
>  
>   sdev_printk(KERN_INFO, sdev,
>   "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n",

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 20/23] scsi_dh_alua: Recheck state on unit attention

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> When we receive a unit attention code of 'ALUA state changed'
> we should recheck the state, as it might be due to an implicit
> ALUA state transition.
> At the same time a workqueue item might already be queued, which
> should be started immediately to avoid any delays.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 48 
> +++---
>  1 file changed, 24 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 85fd597..8717fd3 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -118,7 +118,7 @@ static char print_alua_state(int);
>  static void alua_rtpg_work(struct work_struct *work);
>  static void alua_stpg_work(struct work_struct *work);
>  static void alua_qdata_work(struct work_struct *work);
> -static void alua_check(struct scsi_device *sdev);
> +static void alua_check(struct scsi_device *sdev, bool force);
>  
>  static void release_port_group(struct kref *kref)
>  {
> @@ -423,7 +423,7 @@ static char print_alua_state(int state)
>  }
>  
>  static int alua_check_sense(struct scsi_device *sdev,
> - struct scsi_sense_hdr *sense_hdr)
> +  struct scsi_sense_hdr *sense_hdr)
>  {
>   switch (sense_hdr->sense_key) {
>   case NOT_READY:
> @@ -432,36 +432,34 @@ static int alua_check_sense(struct scsi_device *sdev,
>* LUN Not Accessible - ALUA state transition
>* Kickoff worker to update internal state.
>*/
> - alua_check(sdev);
> - return ADD_TO_MLQUEUE;
> + alua_check(sdev, false);
> + return NEEDS_RETRY;
>   }
>   break;
>   case UNIT_ATTENTION:
> - if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
> - /*
> -  * Power On, Reset, or Bus Device Reset, just retry.
> -  */
> - return ADD_TO_MLQUEUE;
> - if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x04)
> - /*
> -  * Device internal reset
> -  */
> - return ADD_TO_MLQUEUE;
> - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x01)
> + if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) {
>   /*
> -  * Mode Parameter Changed
> +  * Power On, Reset, or Bus Device Reset.
> +  * Might have obscured a state transition,
> +  * so schedule a recheck.
>*/
> + alua_check(sdev, true);
>   return ADD_TO_MLQUEUE;
> - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06)
> + }
> + if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
>   /*
>* ALUA state changed
>*/
> + alua_check(sdev, true);
>   return ADD_TO_MLQUEUE;
> - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07)
> + }
> + if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
>   /*
>* Implicit ALUA state transition failed
>*/
> + alua_check(sdev, true);
>   return ADD_TO_MLQUEUE;
> + }
>   break;
>   }
>  
> @@ -811,7 +809,7 @@ static void alua_qdata_work(struct work_struct *work)
>  
>  static void alua_rtpg_queue(struct alua_port_group *pg,
>   struct scsi_device *sdev,
> - struct alua_queue_data *qdata)
> + struct alua_queue_data *qdata, bool force)
>  {
>   int start_queue = 0;
>   unsigned long flags;
> @@ -832,7 +830,9 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
>   pg->rtpg_sdev = sdev;
>   scsi_device_get(sdev);
>   start_queue = 1;
> - }
> + } else if (!(pg->flags & ALUA_PG_RUN_RTPG) && force)
> + start_queue = 1;
> +
>   spin_unlock_irqrestore(&pg->rtpg_lock, flags);
>  
>   if (start_queue)
> @@ -873,7 +873,7 @@ static int alua_initialize(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   mutex_unlock(&h->init_mutex);
>   if (pg) {
>   pg->expiry = 0;
> - alua_rtpg_queue(pg, sdev, NULL);
> + alua_rtpg_queue(pg, sdev, NULL, true);
>   kref_put(&pg->kref, release_port_group);
>   }
>   return error;
> @@ -982,7 +982,7 @@ static int alua_activate(struct scsi_device *sdev,
> 

Re: [PATCH 19/23] scsi_dh_alua: Use workqueue for RTPG

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> The current ALUA device_handler has two drawbacks:
> - We're sending a 'SET TARGET PORT GROUP' command to every LUN,
>   disregarding the fact that several LUNs might be in a port group
>   and will be automatically switched whenever _any_ LUN within
>   that port group receives the command.
> - Whenever a LUN is in 'transitioning' mode we cannot block I/O
>   to that LUN, instead the controller has to abort the command.
>   This leads to increased traffic across the wire and heavy load
>   on the controller during switchover.

I'm not sure I understand what this means - why couldn't we block I/O?
and what does 'heavy load' mean?  Aborting commands is 'heavy load'?

> 
> With this patch the RTPG handling is moved to a per-portgroup
> workqueue. This reduces the number of 'REPORT TARGET PORT GROUP'
> and 'SET TARGET PORT GROUPS' sent to the controller as we're sending
> them now per port group, and not per device as previously.
> It also allows us to block I/O to any LUN / port group found to be
> in 'transitioning' ALUA mode, as the workqueue item will be requeued
> until the controller moves out of transitioning.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 414 
> -
>  1 file changed, 349 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index b52db8b..85fd597 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -22,6 +22,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -59,10 +61,15 @@
>  #define ALUA_RTPG_SIZE   128
>  #define ALUA_FAILOVER_TIMEOUT60
>  #define ALUA_FAILOVER_RETRIES5
> +#define ALUA_RTPG_DELAY_MSECS5
>  
>  /* device handler flags */
> -#define ALUA_OPTIMIZE_STPG   1
> -#define ALUA_RTPG_EXT_HDR_UNSUPP 2
> +#define ALUA_OPTIMIZE_STPG   0x01
> +#define ALUA_RTPG_EXT_HDR_UNSUPP 0x02
> +/* State machine flags */
> +#define ALUA_PG_RUN_RTPG 0x10
> +#define ALUA_PG_RUN_STPG 0x20
> +
>  
>  static LIST_HEAD(port_group_list);
>  static DEFINE_SPINLOCK(port_group_lock);
> @@ -78,13 +85,28 @@ struct alua_port_group {
>   int pref;
>   unsignedflags; /* used for optimizing STPG */
>   unsigned char   transition_tmo;
> + unsigned long   expiry;
> + unsigned long   interval;
> + struct workqueue_struct *work_q;
> + struct delayed_work rtpg_work;
> + struct delayed_work stpg_work;
> + struct delayed_work qdata_work;
> + spinlock_t  rtpg_lock;
> + struct list_headrtpg_list;
> + struct scsi_device  *rtpg_sdev;
>  };
>  
>  struct alua_dh_data {
>   struct alua_port_group  *pg;
> + spinlock_t  pg_lock;
>   int rel_port;
>   int tpgs;
> - struct scsi_device  *sdev;
> + int init_error;
> + struct mutexinit_mutex;
> +};
> +
> +struct alua_queue_data {
> + struct list_headentry;
>   activate_complete   callback_fn;
>   void*callback_data;
>  };
> @@ -93,6 +115,10 @@ struct alua_dh_data {
>  #define ALUA_POLICY_SWITCH_ALL   1
>  
>  static char print_alua_state(int);
> +static void alua_rtpg_work(struct work_struct *work);
> +static void alua_stpg_work(struct work_struct *work);
> +static void alua_qdata_work(struct work_struct *work);
> +static void alua_check(struct scsi_device *sdev);
>  
>  static void release_port_group(struct kref *kref)
>  {
> @@ -103,6 +129,9 @@ static void release_port_group(struct kref *kref)
>   spin_lock(&port_group_lock);
>   list_del(&pg->node);
>   spin_unlock(&port_group_lock);
> + WARN_ON(pg->rtpg_sdev);
> + if (pg->work_q)
> + destroy_workqueue(pg->work_q);
>   kfree(pg);
>  }
>  
> @@ -296,13 +325,17 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   if (strncmp(tmp_pg->device_id_str, device_id_str,
>   device_id_size))
>   continue;
> - h->pg = tmp_pg;
>   kref_get(&tmp_pg->kref);
> + spin_lock(&h->pg_lock);
> + rcu_assign_pointer(h->pg, tmp_pg);
> + spin_unlock(&h->pg_lock);
>   break;
>   }
>   spin_unlock(&port_group_lock);
> - if (h->pg)
> + if (h->pg) {
> + synchronize_rcu();
>   return SCSI_DH_OK;
> + }
>  
>   pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL);
>   if (!pg) {
> @@ -322,6 +355,19 @@ static int alua_check_vpd(struct scsi_device 

Re: [PATCH 18/23] revert "scsi_dh_alua: ALUA hander attach should succeed while TPG is transitioning"

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> This reverts commit a8e5a2d593cbfccf530c3382c2c328d2edaa7b66
> 
> Obsoleted by the next patch.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 29 +++--
>  1 file changed, 11 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index c2b2100b..b52db8b 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -418,13 +418,12 @@ static int alua_check_sense(struct scsi_device *sdev,
>  /*
>   * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
>   * @sdev: the device to be evaluated.
> - * @wait_for_transition: if nonzero, wait ALUA_FAILOVER_TIMEOUT seconds for 
> device to exit transitioning state
>   *
>   * Evaluate the Target Port Group State.
>   * Returns SCSI_DH_DEV_OFFLINED if the path is
>   * found to be unusable.
>   */
> -static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg, 
> int wait_for_transition)
> +static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
>  {
>   struct scsi_sense_hdr sense_hdr;
>   int len, k, off, valid_states = 0, bufflen = ALUA_RTPG_SIZE;
> @@ -517,8 +516,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg, int w
>   else
>   pg->transition_tmo = ALUA_FAILOVER_TIMEOUT;
>  
> - if (wait_for_transition &&
> - (orig_transition_tmo != pg->transition_tmo)) {
> + if (orig_transition_tmo != pg->transition_tmo) {
>   sdev_printk(KERN_INFO, sdev,
>   "%s: transition timeout set to %d seconds\n",
>   ALUA_DH_NAME, pg->transition_tmo);
> @@ -556,19 +554,14 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg, int w
>  
>   switch (pg->state) {
>   case TPGS_STATE_TRANSITIONING:
> - if (wait_for_transition) {
> - if (time_before(jiffies, expiry)) {
> - /* State transition, retry */
> - interval += 2000;
> - msleep(interval);
> - goto retry;
> - }
> - err = SCSI_DH_RETRY;
> - } else {
> - err = SCSI_DH_OK;
> + if (time_before(jiffies, expiry)) {
> + /* State transition, retry */
> + interval += 2000;
> + msleep(interval);
> + goto retry;
>   }
> -
>   /* Transitioning time exceeded, set port to standby */
> + err = SCSI_DH_RETRY;
>   pg->state = TPGS_STATE_STANDBY;
>   break;
>   case TPGS_STATE_OFFLINE:
> @@ -665,7 +658,7 @@ static int alua_initialize(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   goto out;
>  
>   kref_get(&h->pg->kref);
> - err = alua_rtpg(sdev, h->pg, 0);
> + err = alua_rtpg(sdev, h->pg);
>   kref_put(&h->pg->kref, release_port_group);
>  out:
>   return err;
> @@ -739,14 +732,14 @@ static int alua_activate(struct scsi_device *sdev,
>   if (optimize_stpg)
>   h->pg->flags |= ALUA_OPTIMIZE_STPG;
>  
> - err = alua_rtpg(sdev, h->pg, 1);
> + err = alua_rtpg(sdev, h->pg);
>   if (err != SCSI_DH_OK) {
>   kref_put(&h->pg->kref, release_port_group);
>   goto out;
>   }
>   err = alua_stpg(sdev, h->pg);
>   if (err == SCSI_DH_RETRY)
> - err = alua_rtpg(sdev, h->pg, 1);
> + err = alua_rtpg(sdev, h->pg);
>   kref_put(&h->pg->kref, release_port_group);
>  out:
>   if (fn)

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 17/23] scsi_dh_alua: use unique device id

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Use scsi_vpd_lun_id() to assign a unique device identification
> to the alua port group structure.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 70 
> +++---
>  1 file changed, 65 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index dbe9ff2..c2b2100b 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -70,6 +70,8 @@ static DEFINE_SPINLOCK(port_group_lock);
>  struct alua_port_group {
>   struct kref kref;
>   struct list_headnode;
> + unsigned char   device_id_str[256];
> + int device_id_size;

I prefer _len instead of _size, _size should refer to the size of the buffer,
not the current length of the data in it.

>   int group_id;
>   int tpgs;
>   int state;
> @@ -229,7 +231,9 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>  {
>   unsigned char *d;
>   int group_id = -1;
> - struct alua_port_group *pg = NULL;
> + char device_id_str[256];
> + int device_id_size;
> + struct alua_port_group *tmp_pg, *pg = NULL;
>  
>   if (!sdev->vpd_pg83)
>   return SCSI_DH_DEV_UNSUPP;
> @@ -266,9 +270,39 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   h->tpgs = TPGS_MODE_NONE;
>   return SCSI_DH_DEV_UNSUPP;
>   }
> + device_id_size = scsi_vpd_lun_id(sdev, device_id_str, 256);

should be sizeof(device_id_str) not hardcoded 256

> + if (device_id_size <= 0) {
> + /*
> +  * Internal error: TPGS supported by no

"Internal error: TPGS supported by no"  should be "but no"

> +  * device identifcation found.
> +  * Disable ALUA support.
> +  */
> + sdev_printk(KERN_INFO, sdev,
> + "%s: No device descriptors found\n",
> + ALUA_DH_NAME);
> + h->tpgs = TPGS_MODE_NONE;
> + return SCSI_DH_DEV_UNSUPP;
> + }
>   sdev_printk(KERN_INFO, sdev,
> - "%s: port group %02x rel port %02x\n",
> - ALUA_DH_NAME, group_id, h->rel_port);
> + "%s: device %s port group %02x "
> + "rel port %02x\n", ALUA_DH_NAME,
> + device_id_str, group_id, h->rel_port);
> + spin_lock(&port_group_lock);
> + list_for_each_entry(tmp_pg, &port_group_list, node) {
> + if (tmp_pg->group_id != group_id)
> + continue;
> + if (tmp_pg->device_id_size != device_id_size)
> + continue;
> + if (strncmp(tmp_pg->device_id_str, device_id_str,
> + device_id_size))
> + continue;
> + h->pg = tmp_pg;
> + kref_get(&tmp_pg->kref);
> + break;
> + }
> + spin_unlock(&port_group_lock);
> + if (h->pg)
> + return SCSI_DH_OK;

The lookup checks whether h->pg == NULL but the function never
explicitly sets it to NULL before iterating.

>  
>   pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL);
>   if (!pg) {
> @@ -278,13 +312,39 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   /* Temporary failure, bypass */
>   return SCSI_DH_DEV_TEMP_BUSY;
>   }
> + if (device_id_size)
> + strncpy(pg->device_id_str, device_id_str, 256);

should be sizeof(device_id_str) not hardcoded 256

> + else
> + pg->device_id_str[0] = '\0';
> +
> + pg->device_id_size = device_id_size;
>   pg->group_id = group_id;
>   pg->tpgs = h->tpgs;
>   pg->state = TPGS_STATE_OPTIMIZED;
>   kref_init(&pg->kref);
>   spin_lock(&port_group_lock);
> - list_add(&pg->node, &port_group_list);
> - h->pg = pg;
> + /*
> +  * Re-check list again to catch
> +  * concurrent updates
> +  */
> + list_for_each_entry(tmp_pg, &port_group_list, node) {
> + if (tmp_pg->group_id != pg->group_id)
> + continue;
> + if (tmp_pg->device_id_size != pg->device_id_size)
> + continue;
> + if (strncmp(tmp_pg->device_id_str, pg->device_id_str,
> + device_id_size))
> + continue;
> + h->pg = tmp_pg;
> + kref_get(&tmp_pg->kref);
> + kfree(pg);

With the added check for an existing alua_port_group object, and the kfree() of
the alua_port_group that had been allocated if an existing one is found, the 
code does not
do a destroy_workqueue() on pg->work_q.  

> + pg = NULL;
> + 

Re: [PATCH 16/23] scsi: Add scsi_vpd_lun_id()

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Add 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.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/scsi_lib.c| 121 
> +
>  include/scsi/scsi_device.h |   1 +
>  2 files changed, 122 insertions(+)
> 
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 2a864b8..48d6ff6 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -3145,3 +3145,124 @@ 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.
> + */
> +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;
> + int id_size = -EAGAIN;
> +
> + /*
> +  * 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)
> + return -EINVAL;
> +
> + memset(id, 0, id_len);
> + d = sdev->vpd_pg83 + 4;
> + while (d < sdev->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",
> + 

Re: [PATCH 15/23] scsi_dh_alua: simplify sense code handling

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> 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: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 50 
> +++---
>  1 file changed, 11 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 4157fe2..dbe9ff2 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -91,7 +91,6 @@ struct alua_dh_data {
>  #define ALUA_POLICY_SWITCH_ALL   1
>  
>  static char print_alua_state(int);
> -static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
>  
>  static void release_port_group(struct kref *kref)
>  {
> @@ -323,28 +322,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)
> @@ -359,7 +336,7 @@ static int alua_check_sense(struct scsi_device *sdev,
>   return ADD_TO_MLQUEUE;
>   if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x01)
>   /*
> -  * Mode Parameters Changed
> +  * Mode Parameter Changed

See below.

>*/
>   return ADD_TO_MLQUEUE;
>   if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06)
> @@ -372,18 +349,6 @@ static int alua_check_sense(struct scsi_device *sdev,
>* Implicit ALUA state transition failed
>*/
>   return ADD_TO_MLQUEUE;
> - if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x03)
> - /*
> -  * Inquiry data has changed
> -  */
> - return ADD_TO_MLQUEUE;

??? See below.

> - if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x0e)
> - /*
> -  * REPORTED_LUNS_DATA_HAS_CHANGED is reported
> -  * when switching controllers on targets like
> -  * Intel Multi-Flex. We can just retry.
> -  */
> - return ADD_TO_MLQUEUE;

??? See below.

>   break;
>   }
>  
> @@ -448,9 +413,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg, int w
>   pg->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);

"Mode Parameters Changed" comment should not have been changed to "Mode 
Parameter Changed".
The actual T10 text is "Mode Parameters Changed", so leave it t

Re: [PATCH 14/23] scsi_dh_alua: allocate RTPG buffer separately

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> The RTPG buffer will only evaluated within alua_rtpg(),
> so we can allocate it locally there and avoid having to
> put it into the global structure.
> 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 56 
> +++---
>  1 file changed, 21 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index d1010dd..4157fe2 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -56,7 +56,7 @@
>  #define TPGS_MODE_IMPLICIT   0x1
>  #define TPGS_MODE_EXPLICIT   0x2
>  
> -#define ALUA_INQUIRY_SIZE36
> +#define ALUA_RTPG_SIZE   128
>  #define ALUA_FAILOVER_TIMEOUT60
>  #define ALUA_FAILOVER_RETRIES5
>  
> @@ -75,9 +75,6 @@ struct alua_port_group {
>   int state;
>   int pref;
>   unsignedflags; /* used for optimizing STPG */
> - unsigned char   inq[ALUA_INQUIRY_SIZE];
> - unsigned char   *buff;
> - int bufflen;
>   unsigned char   transition_tmo;
>  };
>  
> @@ -96,21 +93,6 @@ struct alua_dh_data {
>  static char print_alua_state(int);
>  static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
>  
> -static int realloc_buffer(struct alua_port_group *pg, unsigned len)
> -{
> - if (pg->buff && pg->buff != pg->inq)
> - kfree(pg->buff);
> -
> - pg->buff = kmalloc(len, GFP_NOIO);
> - if (!pg->buff) {
> - pg->buff = pg->inq;
> - pg->bufflen = ALUA_INQUIRY_SIZE;
> - return 1;
> - }
> - pg->bufflen = len;
> - return 0;
> -}
> -
>  static void release_port_group(struct kref *kref)
>  {
>   struct alua_port_group *pg;
> @@ -120,8 +102,6 @@ static void release_port_group(struct kref *kref)
>   spin_lock(&port_group_lock);
>   list_del(&pg->node);
>   spin_unlock(&port_group_lock);
> - if (pg->buff && pg->inq != pg->buff)
> - kfree(pg->buff);
>   kfree(pg);
>  }
>  
> @@ -300,8 +280,6 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   return SCSI_DH_DEV_TEMP_BUSY;
>   }
>   pg->group_id = group_id;
> - pg->buff = pg->inq;
> - pg->bufflen = ALUA_INQUIRY_SIZE;
>   pg->tpgs = h->tpgs;
>   pg->state = TPGS_STATE_OPTIMIZED;
>   kref_init(&pg->kref);
> @@ -424,8 +402,8 @@ static int alua_check_sense(struct scsi_device *sdev,
>  static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg, 
> int wait_for_transition)
>  {
>   struct scsi_sense_hdr sense_hdr;
> - int len, k, off, valid_states = 0;
> - unsigned char *ucp;
> + int len, k, off, valid_states = 0, bufflen = ALUA_RTPG_SIZE;
> + unsigned char *ucp, *buff;
>   unsigned err, retval;
>   unsigned long expiry, interval = 0;
>   unsigned int tpg_desc_tbl_off;
> @@ -436,9 +414,12 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg, int w
>   else
>   expiry = round_jiffies_up(jiffies + pg->transition_tmo * HZ);
>  
> + buff = kzalloc(bufflen, GFP_KERNEL);
> + if (!buff)
> + return SCSI_DH_DEV_TEMP_BUSY;
> +
>   retry:
> - retval = submit_rtpg(sdev, pg->buff, pg->bufflen,
> -  &sense_hdr, pg->flags);
> + retval = submit_rtpg(sdev, buff, bufflen, &sense_hdr, pg->flags);
>  
>   if (retval) {
>   if (!scsi_sense_valid(&sense_hdr)) {
> @@ -449,6 +430,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg, int w
>   err = SCSI_DH_DEV_TEMP_BUSY;
>   else
>   err = SCSI_DH_IO;
> + kfree(buff);
>   return err;
>   }
>  
> @@ -477,14 +459,18 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_port_group *pg, int w
>   sdev_printk(KERN_ERR, sdev, "%s: rtpg failed\n",
>   ALUA_DH_NAME);
>   scsi_print_sense_hdr(sdev, ALUA_DH_NAME, &sense_hdr);
> + kfree(buff);
>   return SCSI_DH_IO;
>   }
>  
> - len = get_unaligned_be32(&pg->buff[0]) + 4;
> + len = get_unaligned_be32(&buff[0]) + 4;
>  
> - if (len > pg->bufflen) {
> + if (len > bufflen) {
>   /* Resubmit with the correct length */
> - if (realloc_buffer(pg, len)) {
> + kfree(buff);
> + bufflen = len;
> + buff = kmalloc(bufflen, GFP_KERNEL);
> + if (!buff) {
>   sdev_printk(KERN_WARNING, sdev,
>   "%s: kmalloc buffe

Re: [PATCH 13/23] scsi_dh_alua: Use separate alua_port_group structure

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> The port group needs to be a separate structure as several
> LUNs might belong to the same group.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 211 
> +++--
>  1 file changed, 139 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index ef4363a..d1010dd 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -64,9 +64,13 @@
>  #define ALUA_OPTIMIZE_STPG   1
>  #define ALUA_RTPG_EXT_HDR_UNSUPP 2
>  
> -struct alua_dh_data {
> +static LIST_HEAD(port_group_list);
> +static DEFINE_SPINLOCK(port_group_lock);
> +
> +struct alua_port_group {
> + struct kref kref;
> + struct list_headnode;
>   int group_id;
> - int rel_port;
>   int tpgs;
>   int state;
>   int pref;
> @@ -75,6 +79,12 @@ struct alua_dh_data {
>   unsigned char   *buff;
>   int bufflen;
>   unsigned char   transition_tmo;
> +};
> +
> +struct alua_dh_data {
> + struct alua_port_group  *pg;
> + int rel_port;
> + int tpgs;
>   struct scsi_device  *sdev;
>   activate_complete   callback_fn;
>   void*callback_data;
> @@ -86,21 +96,35 @@ struct alua_dh_data {
>  static 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)
> +static int realloc_buffer(struct alua_port_group *pg, unsigned len)
>  {
> - if (h->buff && h->buff != h->inq)
> - kfree(h->buff);
> + if (pg->buff && pg->buff != pg->inq)
> + kfree(pg->buff);
>  
> - h->buff = kmalloc(len, GFP_NOIO);
> - if (!h->buff) {
> - h->buff = h->inq;
> - h->bufflen = ALUA_INQUIRY_SIZE;
> + pg->buff = kmalloc(len, GFP_NOIO);
> + if (!pg->buff) {
> + pg->buff = pg->inq;
> + pg->bufflen = ALUA_INQUIRY_SIZE;
>   return 1;
>   }
> - h->bufflen = len;
> + pg->bufflen = len;
>   return 0;
>  }
>  
> +static void release_port_group(struct kref *kref)
> +{
> + struct alua_port_group *pg;
> +
> + pg = container_of(kref, struct alua_port_group, kref);
> + printk(KERN_WARNING "alua: release port group %d\n", pg->group_id);
> + spin_lock(&port_group_lock);
> + list_del(&pg->node);
> + spin_unlock(&port_group_lock);
> + if (pg->buff && pg->inq != pg->buff)
> + kfree(pg->buff);
> + kfree(pg);
> +}
> +
>  /*
>   * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
>   * @sdev: sdev the command should be sent to
> @@ -225,6 +249,8 @@ static int alua_check_tpgs(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>  static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h)
>  {
>   unsigned char *d;
> + int group_id = -1;
> + struct alua_port_group *pg = NULL;
>  
>   if (!sdev->vpd_pg83)
>   return SCSI_DH_DEV_UNSUPP;
> @@ -241,7 +267,7 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   break;
>   case 0x5:
>   /* Target port group */
> - h->group_id = get_unaligned_be16(&d[6]);
> + group_id = get_unaligned_be16(&d[6]);
>   break;
>   default:
>   break;
> @@ -249,7 +275,7 @@ static int alua_check_vpd(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>   d += d[3] + 4;
>   }
>  
> - if (h->group_id == -1) {
> + if (group_id == -1) {
>   /*
>* Internal error; TPGS supported but required
>* VPD identification descriptors not present.
> @@ -258,15 +284,33 @@ 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;
>   }
>   sdev_printk(KERN_INFO, sdev,
>   "%s: port group %02x rel port %02x\n",
> - ALUA_DH_NAME, h->group_id, h->rel_port);
> + ALUA_DH_NAME, group_id, h->rel_port);
>  
> - return 0;
> + pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL);
> + if (!pg) {
> + sdev_printk(KERN_WARNING, sdev,
> + "%s: kzalloc port group failed\n",
> +   

Re: [PATCH 12/23] scsi_dh_alua: switch to scsi_execute_req_flags()

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> All commands are issued synchronously, so no need to open-code
> scsi_execute_req_flags() anymore. And we can get rid of the
> static sense code structure element.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 124 
> -
>  1 file changed, 34 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index fd0385e..ef4363a 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -75,8 +75,6 @@ struct alua_dh_data {
>   unsigned char   *buff;
>   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;
> @@ -103,72 +101,30 @@ static int realloc_buffer(struct alua_dh_data *h, 
> unsigned len)
>   return 0;
>  }
>  
> -static struct request *get_alua_req(struct scsi_device *sdev,
> - void *buffer, unsigned buflen, int rw)
> -{
> - struct request *rq;
> - struct request_queue *q = sdev->request_queue;
> -
> - rq = blk_get_request(q, rw, GFP_NOIO);
> -
> - if (IS_ERR(rq)) {
> - sdev_printk(KERN_INFO, sdev,
> - "%s: blk_get_request failed\n", __func__);
> - return NULL;
> - }
> - blk_rq_set_block_pc(rq);
> -
> - if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
> - blk_put_request(rq);
> - sdev_printk(KERN_INFO, sdev,
> - "%s: blk_rq_map_kern failed\n", __func__);
> - return NULL;
> - }
> -
> - rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
> -  REQ_FAILFAST_DRIVER;
> - rq->retries = ALUA_FAILOVER_RETRIES;
> - rq->timeout = ALUA_FAILOVER_TIMEOUT * HZ;
> -
> - return rq;
> -}
> -
>  /*
>   * 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, unsigned char *buff,
> - int bufflen, unsigned char *sense, int flags)
> +static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
> +int bufflen, struct scsi_sense_hdr *sshdr, int flags)
>  {
> - struct request *rq;
> - int err = 0;
> -
> - rq = get_alua_req(sdev, buff, bufflen, READ);
> - if (!rq) {
> - err = DRIVER_BUSY << 24;
> - goto done;
> - }
> + u8 cdb[16];

See below.

> + int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
> + REQ_FAILFAST_DRIVER;
>  
>   /* Prepare the command. */
> - rq->cmd[0] = MAINTENANCE_IN;
> + memset(cdb, 0x0, 16);

See below.

> + cdb[0] = MAINTENANCE_IN;
>   if (!(flags & ALUA_RTPG_EXT_HDR_UNSUPP))
> - rq->cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
> + cdb[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
>   else
> - rq->cmd[1] = MI_REPORT_TARGET_PGS;
> - put_unaligned_be32(bufflen, &rq->cmd[6]);
> - rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
> -
> - rq->sense = sense;
> - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
> - rq->sense_len = 0;
> + cdb[1] = MI_REPORT_TARGET_PGS;
> + put_unaligned_be32(bufflen, &cdb[6]);
>  
> - blk_execute_rq(rq->q, NULL, rq, 1);
> - if (rq->errors)
> - err = rq->errors;
> -
> - blk_put_request(rq);
> -done:
> - return err;
> + return scsi_execute_req_flags(sdev, cdb, DMA_FROM_DEVICE,
> +   buff, bufflen, sshdr,
> +   ALUA_FAILOVER_TIMEOUT * HZ,
> +   ALUA_FAILOVER_RETRIES, NULL, req_flags);
>  }
>  
>  /*
> @@ -178,40 +134,30 @@ done:
>   * to 'active/optimized' and let the array firmware figure out
>   * the states of the remaining groups.
>   */
> -static unsigned submit_stpg(struct scsi_device *sdev, int group_id,
> - unsigned char *sense)
> +static int submit_stpg(struct scsi_device *sdev, int group_id,
> +struct scsi_sense_hdr *sshdr)
>  {
> - struct request *rq;
> + u8 cdb[COMMAND_SIZE(MAINTENANCE_OUT)];
>   unsigned char stpg_data[8];
>   int stpg_len = 8;
> - int err = 0;
> + int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
> + REQ_FAILFAST_DRIVER;
>  
>   /* Prepare the data buffer */
>   memset(stpg_data, 0, stpg_len);
>   stpg_data[4] = TPGS_STATE_OPTIMIZED & 0x0f;
>   put_unaligned_be16(group_id, &stpg_data[6]);
>  
> - rq = get_alua_req(sd

Re: [PATCH 11/23] scsi_dh_alua: Make stpg synchronous

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> We should be issuing STPG synchronously as we need to
> evaluate the return code on failure.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 179 
> +
>  1 file changed, 83 insertions(+), 96 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 9e2b3af..fd0385e 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -172,76 +172,28 @@ done:
>  }
>  
>  /*
> - * stpg_endio - Evaluate SET TARGET GROUP STATES
> - * @sdev: the device to be evaluated
> - * @state: the new target group state
> - *
> - * Evaluate a SET TARGET GROUP STATES command response.
> - */
> -static void stpg_endio(struct request *req, int error)
> -{
> - struct alua_dh_data *h = req->end_io_data;
> - struct scsi_sense_hdr sense_hdr;
> - unsigned err = SCSI_DH_OK;
> -
> - if (host_byte(req->errors) != DID_OK ||
> - msg_byte(req->errors) != COMMAND_COMPLETE) {
> - err = SCSI_DH_IO;
> - goto done;
> - }
> -
> - if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
> -  &sense_hdr)) {
> - 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 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;
> -
> - if (err == SCSI_DH_OK) {
> - h->state = TPGS_STATE_OPTIMIZED;
> - sdev_printk(KERN_INFO, h->sdev,
> - "%s: port group %02x switched to state %c\n",
> - ALUA_DH_NAME, h->group_id,
> - print_alua_state(h->state));
> - }
> -done:
> - req->end_io_data = NULL;
> - __blk_put_request(req->q, req);
> - if (h->callback_fn) {
> - h->callback_fn(h->callback_data, err);
> - h->callback_fn = h->callback_data = NULL;
> - }
> - return;
> -}
> -
> -/*
>   * submit_stpg - Issue a SET TARGET GROUP STATES command
>   *
>   * Currently we're only setting the current target port group state
>   * to 'active/optimized' and let the array firmware figure out
>   * the states of the remaining groups.
>   */
> -static unsigned submit_stpg(struct alua_dh_data *h)
> +static unsigned submit_stpg(struct scsi_device *sdev, int group_id,
> + unsigned char *sense)
>  {
>   struct request *rq;
> + unsigned char stpg_data[8];
>   int stpg_len = 8;
> - struct scsi_device *sdev = h->sdev;
> + int err = 0;
>  
>   /* Prepare the data buffer */
> - memset(h->buff, 0, stpg_len);
> - h->buff[4] = TPGS_STATE_OPTIMIZED & 0x0f;
> - put_unaligned_be16(h->group_id, &h->buff[6]);
> + memset(stpg_data, 0, stpg_len);
> + stpg_data[4] = TPGS_STATE_OPTIMIZED & 0x0f;
> + put_unaligned_be16(group_id, &stpg_data[6]);
>  
> - rq = get_alua_req(sdev, h->buff, stpg_len, WRITE);
> + rq = get_alua_req(sdev, stpg_data, stpg_len, WRITE);
>   if (!rq)
> - return SCSI_DH_RES_TEMP_UNAVAIL;
> + return DRIVER_BUSY << 24;
>  
>   /* Prepare the command. */
>   rq->cmd[0] = MAINTENANCE_OUT;
> @@ -249,13 +201,17 @@ static unsigned submit_stpg(struct alua_dh_data *h)
>   put_unaligned_be32(stpg_len, &rq->cmd[6]);
>   rq->cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
>  
> - rq->sense = h->sense;
> + rq->sense = sense;
>   memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
> - rq->sense_len = h->senselen = 0;
> - rq->end_io_data = h;
> + rq->sense_len = 0;
> +
> + blk_execute_rq(rq->q, NULL, rq, 1);
> + if (rq->errors)
> + err = rq->errors;
> +
> + blk_put_request(rq);
>  
> - blk_execute_rq_nowait(rq->q, NULL, rq, 1, stpg_endio);
> - return SCSI_DH_OK;
> + return err;
>  }
>  
>  /*
> @@ -619,6 +575,68 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
> alua_dh_data *h, int wait_
>  }
>  
>  /*
> + * alua_stpg - Issue a SET TARGET GROUP STATES command
> + *
> + * Issue a SET TARGET GROUP STATES command and evaluate the
> + * response. Returns SCSI_DH_RETRY per default to trigger
> + * a re-evaluation of the target group state.
> + */
> +static unsigned alua_stpg(struct scsi_device *sdev, struct alua_dh_data *h)
> +{
> + int retval;
> + struct scsi_sense_hdr sense_hdr;
> +
> + if (!(h->tpgs & TPGS_MODE_EXPLICIT)) {
> + /* Only implicit ALUA supported, retry */
> + return SCSI_DH_RETRY;
> + }
> + switch (h->state) {
> + case TPGS_STATE_

Re: [PATCH 07/23] scsi: remove scsi_show_sense_hdr()

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Last caller is gone, so remove it.
> 
> Reviewed-by: Bart Van Assche 
> Reviewed-by: Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  include/scsi/scsi_dbg.h | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
> index f8170e9..56710e0 100644
> --- a/include/scsi/scsi_dbg.h
> +++ b/include/scsi/scsi_dbg.h
> @@ -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 *);

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 10/23] scsi_dh_alua: Pass buffer as function argument

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Pass in the buffer as a function argument for submit_rtpg().
> 
> Reviewed-by: Bart Van Assche 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 0636721..9e2b3af 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -137,12 +137,13 @@ 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)
> +static unsigned submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
> + int bufflen, unsigned char *sense, int flags)
>  {
>   struct request *rq;
>   int err = 0;
>  
> - rq = get_alua_req(sdev, h->buff, h->bufflen, READ);
> + rq = get_alua_req(sdev, buff, bufflen, READ);
>   if (!rq) {
>   err = DRIVER_BUSY << 24;
>   goto done;
> @@ -150,22 +151,21 @@ static unsigned submit_rtpg(struct scsi_device *sdev, 
> struct alua_dh_data *h)
>  
>   /* Prepare the command. */
>   rq->cmd[0] = MAINTENANCE_IN;
> - if (!(h->flags & ALUA_RTPG_EXT_HDR_UNSUPP))
> + if (!(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;
> - put_unaligned_be32(h->bufflen, &rq->cmd[6]);
> + put_unaligned_be32(bufflen, &rq->cmd[6]);
>   rq->cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
>  
> - rq->sense = h->sense;
> + rq->sense = sense;
>   memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
> - rq->sense_len = h->senselen = 0;
> + rq->sense_len = 0;
>  
>   blk_execute_rq(rq->q, NULL, rq, 1);
> - if (rq->errors) {
> + if (rq->errors)
>   err = rq->errors;
> - h->senselen = rq->sense_len;
> - }
> +
>   blk_put_request(rq);
>  done:
>   return err;
> @@ -491,7 +491,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);
> + retval = submit_rtpg(sdev, h->buff, h->bufflen, h->sense, h->flags);
>  
>   if (retval) {
>   if (!scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,

This patch also removes the setting of h->senselen, you should mention
that in the patch description.  Or, perhaps the removal of h->senselen
should have been done as part of patch 12/23, which removed the senselen
field (and the sense buffer field) from the alua_dh_data structure.

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 08/23] scsi_dh_alua: use flag for RTPG extended header

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> 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 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 15 +++
>  1 file changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 25c2045..9d8fc53 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -59,8 +59,9 @@
>  #define ALUA_FAILOVER_TIMEOUT60
>  #define ALUA_FAILOVER_RETRIES5
>  
> -/* flags passed from user level */
> +/* device handler flags */
>  #define ALUA_OPTIMIZE_STPG   1
> +#define ALUA_RTPG_EXT_HDR_UNSUPP 2
>  
>  struct alua_dh_data {
>   int group_id;
> @@ -135,8 +136,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;
> @@ -149,7 +149,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;
> @@ -487,7 +487,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;
> @@ -498,7 +497,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,
> @@ -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;
>   }
>  

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 09/23] scsi_dh_alua: use unaligned access macros

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Use 'get_unaligned_XX' and 'put_unaligned_XX' instead of
> open-coding it.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 23 ---
>  1 file changed, 8 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 9d8fc53..0636721 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -22,6 +22,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -153,10 +154,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;
> @@ -239,8 +237,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)
> @@ -249,10 +246,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;
> @@ -341,11 +335,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];

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 06/23] scsi_dh_alua: fixup description of stpg_endio()

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Fixup copy-and-paste error in the description of stpg_endio().
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index c41d662..25c2045 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -174,13 +174,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)
>  {

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 05/23] scsi_dh_alua: return standard SCSI return codes in submit_rtpg

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Fixup submit_rtpg() to always return a standard SCSI return code.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 38 
> +-
>  1 file changed, 22 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 7b43ee3..c41d662 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -139,11 +139,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;
> @@ -161,13 +163,10 @@ static unsigned submit_rtpg(struct scsi_device *sdev, 
> struct alua_dh_data *h,
>   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: rtpg failed with %x\n",
> - ALUA_DH_NAME, rq->errors);
> + blk_execute_rq(rq->q, NULL, rq, 1);
> + if (rq->errors) {
> + err = rq->errors;
>   h->senselen = rq->sense_len;
> - err = SCSI_DH_IO;
>   }
>   blk_put_request(rq);
>  done:
> @@ -489,7 +488,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;
> @@ -501,13 +500,20 @@ 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 && h->senselen > 0) {
> - err = scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
> -&sense_hdr);
> - if (!err)
> - return 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)) {
> + sdev_printk(KERN_INFO, sdev,
> + "%s: rtpg failed, result %d\n",
> + ALUA_DH_NAME, retval);
> + if (driver_byte(retval) == DRIVER_BUSY)
> + err = SCSI_DH_DEV_TEMP_BUSY;
> + else
> + err = SCSI_DH_IO;
> + return err;
> + }
>  
>   /*
>* submit_rtpg() has failed on existing arrays

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 04/23] scsi_dh_alua: use standard logging functions

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Use standard logging functions instead of hand-crafted ones.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 34 
> +-
>  1 file changed, 15 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index a20c8bf..7b43ee3 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  
> @@ -194,22 +195,16 @@ 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 (!err) {
> - err = SCSI_DH_IO;
> - goto done;
> - }
> + if (scsi_normalize_sense(h->sense, SCSI_SENSE_BUFFERSIZE,
> +  &sense_hdr)) {
>   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;
> @@ -530,16 +525,17 @@ 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;
>  
>   len = (h->buff[0] << 24) + (h->buff[1] << 16) +
>   (h->buff[2] << 8) + h->buff[3] + 4;

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 03/23] scsi_dh_alua: improved logging

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> Issue different logging messages if ALUA is not supported
> or the TPGS setting is invalid.
> 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index f15b977..a20c8bf 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -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;

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 02/23] scsi_dh_alua: Use vpd_pg83 information

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:41 +0200, Hannes Reinecke wrote:
> The SCSI device now has the VPD page 0x83 information attached,
> so there is no need to query it again.
> 
> Reviewed-by: Christoph Hellwig 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 83 
> +-
>  1 file changed, 13 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index 7d01ef0..f15b977 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -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,24 @@ 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;
>  
> - 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;
> - }
> + if (!sdev->vpd_pg83)
> + 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) {
> + d = sdev->vpd_pg83 + 4;
> + while (d < sdev->vpd_pg83 + sdev->vpd_pg83_len) {
>   switch (d[1] & 0xf) {
>   case 0x4:
>   /* Relative target port */
> @@ -422,14 +366,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 +635,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;
>  

Reviewed-by: Ewan D. Milne 



--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
Mo

Re: [PATCH 01/23] scsi_dh_alua: Disable ALUA handling for non-disk devices

2015-09-22 Thread Ewan Milne
On Thu, 2015-08-27 at 14:40 +0200, Hannes Reinecke wrote:
> 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 
> Reviewed-by: Bart Van Assche 
> ---
>  drivers/scsi/device_handler/scsi_dh_alua.c | 12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
> b/drivers/scsi/device_handler/scsi_dh_alua.c
> index cc2773b..7d01ef0 100644
> --- a/drivers/scsi/device_handler/scsi_dh_alua.c
> +++ b/drivers/scsi/device_handler/scsi_dh_alua.c
> @@ -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:

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH RESEND] scsi: Fix sense information setting in fixed sized format

2015-09-03 Thread Ewan Milne
On Thu, 2015-09-03 at 19:49 +0300, Sagi Grimberg wrote:
> In fixed size sense format the information field is a four byte
> field.
> 
> Signed-off-by: Sagi Grimberg 
> Reviewed-by: Martin K. Petersen 
> Reviewed-by: Bart Van Assche 
> Reviewed-by: Christoph Hellwig 
> ---
>  drivers/scsi/scsi_common.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c
> index 41432c10dda2..8cfb7eeb5bbc 100644
> --- a/drivers/scsi/scsi_common.c
> +++ b/drivers/scsi/scsi_common.c
> @@ -270,7 +270,7 @@ void scsi_set_sense_information(u8 *buf, u64 info)
>   put_unaligned_be64(info, &ucp[4]);
>   } else if ((buf[0] & 0x7f) == 0x70) {
>   buf[0] |= 0x80;
> - put_unaligned_be64(info, &buf[3]);
> + put_unaligned_be32(info, &buf[3]);
>   }
>  }
>  EXPORT_SYMBOL(scsi_set_sense_information);

Looks correct per SPC-4 4.5.3

And you did post a patch to target for the case where the sector
did not fit in 32 bits, which requires descriptor format sense, so...

Reviewed-by: Ewan D. Milne 

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


Re: [PATCH 2/2] bfa: Fix incorrect de-reference of pointer

2015-09-03 Thread Ewan Milne
On Thu, 2015-08-13 at 06:41 -0400, anil.gurumur...@qlogic.com wrote:
> From: Anil Gurumurthy 
> 
> Signed-off-by: Anil Gurumurthy 
> Tested-by: Sudarsana Kalluru 
> ---
>  drivers/scsi/bfa/bfa_ioc.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
> index 4e71044..98f7e8c 100644
> --- a/drivers/scsi/bfa/bfa_ioc.c
> +++ b/drivers/scsi/bfa/bfa_ioc.c
> @@ -3878,7 +3878,7 @@ bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct 
> bfi_mbmsg_s *msg)
>   bfa_trc(sfp, sfp->data_valid);
>   if (sfp->data_valid) {
>   u32 size = sizeof(struct sfp_mem_s);
> - u8 *des = (u8 *) &(sfp->sfpmem);
> + u8 *des = (u8 *)(sfp->sfpmem);
>   memcpy(des, sfp->dbuf_kva, size);
>   }
>   /*

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH 1/2] bfa: Fix indentation

2015-09-03 Thread Ewan Milne
On Thu, 2015-08-13 at 06:41 -0400, anil.gurumur...@qlogic.com wrote:
> From: Anil Gurumurthy 
> 
> Signed-off-by: Anil Gurumurthy 
> Tested-by : Sudarasana Kalluru 
> ---
>  drivers/scsi/bfa/bfa_ioc.c |   22 +++---
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
> index 315d6d6..4e71044 100644
> --- a/drivers/scsi/bfa/bfa_ioc.c
> +++ b/drivers/scsi/bfa/bfa_ioc.c
> @@ -3665,19 +3665,19 @@ bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp)
>   if (sfp->state_query_cbfn)
>   sfp->state_query_cbfn(sfp->state_query_cbarg,
>   sfp->status);
> - sfp->media = NULL;
> - }
> + sfp->media = NULL;
> + }
>  
> - if (sfp->portspeed) {
> - sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
> - if (sfp->state_query_cbfn)
> - sfp->state_query_cbfn(sfp->state_query_cbarg,
> - sfp->status);
> - sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
> - }
> + if (sfp->portspeed) {
> + sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
> + if (sfp->state_query_cbfn)
> + sfp->state_query_cbfn(sfp->state_query_cbarg,
> + sfp->status);
> + sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
> + }
>  
> - sfp->state_query_lock = 0;
> - sfp->state_query_cbfn = NULL;
> + sfp->state_query_lock = 0;
> + sfp->state_query_cbfn = NULL;
>  }
>  
>  /*

Reviewed-by: Ewan D. Milne 


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


Re: [scsi 5/7 RESEND] scsi_debug: schedule_resp fix input variable check

2015-08-27 Thread Ewan Milne
On Wed, 2015-08-26 at 16:38 -0700, James Bottomley wrote:
> On Tue, 2015-08-25 at 21:03 +, Winkler, Tomas wrote:
> > 
> > > > +   /* this should never happen */
> > > > +   if (WARN_ON(!cmnd))
> > > > +   return SCSI_MLQUEUE_HOST_BUSY;
> > > >
> > > > -   if (NULL == cmnd || NULL == devip) {
> > > > -   pr_warn("called with NULL cmnd or devip pointer\n");
> > > > +   if (NULL == devip) {
> > > > +   pr_warn("called devip == NULL\n");
> > > > /* no particularly good error to report back */
> > > > return SCSI_MLQUEUE_HOST_BUSY;
> > > > }
> > > 
> > > Please refer to the patch I just posted, we can't return _HOST_BUSY here
> > > if devip == NULL.  I posted a fix against the current "misc" branch as
> > > I don't see this patch applied, let me know if I need to update it.
> > 
> > 
> > I'm just not sure why the patches are not merged or even rejected.
> 
> Because ideally I want a Maintainer ack.  That's Doug Gilbert.
> 
> > I'm submitting patches to the Linux kernel for more than 10 years to
> > various trees and  I can agree that these are not some  urgent fixes,
> > but  this is the first time my effort is ignored for such long time by
> > the maintainer. 
> 
> Well, OK, I trust martin, I'll override the lack of Maintainer ack if
> you fix as Ewan suggests.
> 

Just to clarify, I didn't have a problem with Tomas' patch per se, it's
just that my patch won't apply on top of his.  I'll submit a v2 if you
want, so you can apply Tomas' patch first.  The problem I'm fixing has
been in there for a while.  Let me know if you want me to do that.

-Ewan

> James
> 
> 
> > Thanks
> > Tomas
> > 
> > NrybXǧv^)޺{.n+{"{ayʇڙ,jfhzwj:+vwjmzZ+ݢj"!
> 
> 
> 


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


Re: [scsi 5/7 RESEND] scsi_debug: schedule_resp fix input variable check

2015-08-25 Thread Ewan Milne
On Tue, 2015-07-28 at 16:54 +0300, Tomas Winkler wrote:
> The function should never be called with cmnd NULL so
> put a fat WARN there.
> Fix also smatch wraning:
> schedule_resp() warn: variable dereferenced before check 'cmnd'
> 
> Cc: Douglas Gilbert 
> Signed-off-by: Tomas Winkler 
> Acked-by: Douglas Gilbert 
> ---
>  drivers/scsi/scsi_debug.c | 13 ++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 3a70683cf9f9..faa4ddd8decf 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -3941,13 +3941,20 @@ schedule_resp(struct scsi_cmnd *cmnd, struct 
> sdebug_dev_info *devip,
>   unsigned long iflags;
>   int k, num_in_q, qdepth, inject;
>   struct sdebug_queued_cmd *sqcp = NULL;
> - struct scsi_device *sdp = cmnd->device;
> + struct scsi_device *sdp;
> +
> + /* this should never happen */
> + if (WARN_ON(!cmnd))
> + return SCSI_MLQUEUE_HOST_BUSY;
>  
> - if (NULL == cmnd || NULL == devip) {
> - pr_warn("called with NULL cmnd or devip pointer\n");
> + if (NULL == devip) {
> + pr_warn("called devip == NULL\n");
>   /* no particularly good error to report back */
>   return SCSI_MLQUEUE_HOST_BUSY;
>   }

Please refer to the patch I just posted, we can't return _HOST_BUSY here
if devip == NULL.  I posted a fix against the current "misc" branch as
I don't see this patch applied, let me know if I need to update it.

> +
> + sdp = cmnd->device;
> +
>   if ((scsi_result) && (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
>   sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
>   __func__, scsi_result);


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


Re: [PATCH] scsi: fix memory leak with scsi-mq

2015-07-27 Thread Ewan Milne
On Thu, 2015-07-16 at 11:40 -0400, Tony Battersby wrote:
> Fix a memory leak with scsi-mq triggered by commands with large data
> transfer length.
> 
> __sg_alloc_table() sets both table->nents and table->orig_nents to the
> same value.  When the scatterlist is DMA-mapped, table->nents is
> overwritten with the (possibly smaller) size of the DMA-mapped
> scatterlist, while table->orig_nents retains the original size of the
> allocated scatterlist.  scsi_free_sgtable() should therefore check
> orig_nents instead of nents, and all code that initializes sdb->table
> without calling __sg_alloc_table() should set both nents and orig_nents.
> 
> Fixes: d285203cf647 ("scsi: add support for a blk-mq based I/O path.")
> Cc:  # 3.17+
> Signed-off-by: Tony Battersby 
> ---
> 
> For immediate inclusion.
> 
> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index 106884a..cfadcce 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -944,7 +944,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct 
> scsi_eh_save *ses,
>   scmd->sdb.length);
>   scmd->sdb.table.sgl = &ses->sense_sgl;
>   scmd->sc_data_direction = DMA_FROM_DEVICE;
> - scmd->sdb.table.nents = 1;
> + scmd->sdb.table.nents = scmd->sdb.table.orig_nents = 1;
>   scmd->cmnd[0] = REQUEST_SENSE;
>   scmd->cmnd[4] = scmd->sdb.length;
>   scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]);
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index b1a2631..448ebda 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -583,7 +583,7 @@ static struct scatterlist *scsi_sg_alloc(unsigned int 
> nents, gfp_t gfp_mask)
>  
>  static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq)
>  {
> - if (mq && sdb->table.nents <= SCSI_MAX_SG_SEGMENTS)
> + if (mq && sdb->table.orig_nents <= SCSI_MAX_SG_SEGMENTS)
>   return;
>   __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, mq, scsi_sg_free);
>  }
> @@ -597,8 +597,8 @@ static int scsi_alloc_sgtable(struct scsi_data_buffer 
> *sdb, int nents, bool mq)
>  
>   if (mq) {
>   if (nents <= SCSI_MAX_SG_SEGMENTS) {
> - sdb->table.nents = nents;
> - sg_init_table(sdb->table.sgl, sdb->table.nents);
> + sdb->table.nents = sdb->table.orig_nents = nents;
> + sg_init_table(sdb->table.sgl, nents);
>   return 0;
>   }
>   first_chunk = sdb->table.sgl;
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Looks good.  James, can we get this in please?

Reviewed-by: Ewan D. Milne 


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


Re: [dm-devel] ALUA - rescan device capacity on zero sized block devices

2015-06-12 Thread Ewan Milne
On Fri, 2015-06-12 at 11:17 -0400, Ewan Milne wrote:
> There's an interesting, somewhat-related issue I've come across with
> iSCSI storage, when an event happens while the connection is not
> established (i.e. link down, or logged out for some reason).  The T10
> spec says that UAs are supposed to be reported on the I-T nexuses,

... but if the I-T nexus doesn't exist when the event occurs, it
doesn't get reported when the nexus is re-established, and it does
not seem like there is any requirement to do so.

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


Re: [PATCH] scsi: Add ALUA state change UA handling

2015-06-12 Thread Ewan Milne
Looking at this closely, I didn't get the SDEV_UA text
right in my previous review comment, and I think that
additional enum values really ought to be added to the
end, after existing ones, and code that handles them
should follow suit.  So, here's an adjusted patch...

-Ewan


[PATCH] scsi: Add ALUA state change UA handling

Log the ALUA state change unit attention correctly with
the message log and emit an event to allow user-space
tools to react to it.

Reviewed-by: Ewan D. Milne 
Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/scsi_error.c  |4 
 drivers/scsi/scsi_lib.c|4 
 include/scsi/scsi_device.h |3 ++-
 3 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 4cdaffc..bf7065c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -420,6 +420,10 @@ static void scsi_report_sense(struct scsi_device *sdev,
evt_type = SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED;
sdev_printk(KERN_WARNING, sdev,
"Mode parameters changed");
+   } else if (sshdr->asc == 0x2a && sshdr->ascq == 0x06) {
+   evt_type = SDEV_EVT_ALUA_STATE_CHANGE_REPORTED;
+   sdev_printk(KERN_WARNING, sdev,
+   "Asymmetic access state changed");
} else if (sshdr->asc == 0x2a && sshdr->ascq == 0x09) {
evt_type = SDEV_EVT_CAPACITY_CHANGE_REPORTED;
sdev_printk(KERN_WARNING, sdev,
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 6d5c0b8..62259eb 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2693,6 +2693,9 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
struct scsi_event *evt)
case SDEV_EVT_LUN_CHANGE_REPORTED:
envp[idx++] = "SDEV_UA=REPORTED_LUNS_DATA_HAS_CHANGED";
break;
+   case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
+   envp[idx++] = "SDEV_UA=ASYMMETRIC_ACCESS_STATE_CHANGED";
+   break;
default:
/* do nothing */
break;
@@ -2796,6 +2799,7 @@ struct scsi_event *sdev_evt_alloc(enum scsi_device_event 
evt_type,
case SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED:
case SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED:
case SDEV_EVT_LUN_CHANGE_REPORTED:
+   case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
default:
/* do nothing */
break;
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 2e0281e..0c82aaa 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -57,9 +57,10 @@ enum scsi_device_event {
SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED,   /* 38 07  UA reported */
SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED,/* 2A 01  UA reported */
SDEV_EVT_LUN_CHANGE_REPORTED,   /* 3F 0E  UA reported */
+   SDEV_EVT_ALUA_STATE_CHANGE_REPORTED,/* 2A 06  UA reported */
 
SDEV_EVT_FIRST  = SDEV_EVT_MEDIA_CHANGE,
-   SDEV_EVT_LAST   = SDEV_EVT_LUN_CHANGE_REPORTED,
+   SDEV_EVT_LAST   = SDEV_EVT_ALUA_STATE_CHANGE_REPORTED,
 
SDEV_EVT_MAXBITS= SDEV_EVT_LAST + 1
 };
-- 
1.7.1



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


Re: [dm-devel] ALUA - rescan device capacity on zero sized block devices

2015-06-12 Thread Ewan Milne
On Thu, 2015-06-11 at 07:52 +0200, Hannes Reinecke wrote: 
> On 06/10/2015 05:02 PM, Ewan Milne wrote:
> > On Mon, 2015-04-20 at 07:58 +0200, Hannes Reinecke wrote:
> >> On 04/19/2015 12:56 AM, Christophe Varoqui wrote:
> >>> About five years ago, we faced a somewhat simular issue with
> >>> Symmetrix arrays, where the replicated LU of a SRDF pair (R2) was
> >>> flagged read-only by the kernel upon discovery. Splitting the pair
> >>> with a symcli command  made the LU read-write from the array
> >>> controller point of view, but the Linux kernel would not promote it
> >>> read-write dynamically.
> >>>
> >>> I don't know if the Symmetrix array also use a unit attention to
> >>> signal the change to the initiators. If it does, it might be worth
> >>> trying to address both the 3par peer persistance and the Symmetrix
> >>> SRDF situations.
> >>>
> >>> On the other hand, if the SRDF R2 rw promotion issue has been fixed
> >>> since, the patch might give guidance about where/how to plug the
> >>> 3par peer persistance ghost path rescans.
> >>>
> >> It's not only that; if you are faced with LUNs in standby even the
> >> kernel wouldn't detect them properly.
> >>
> >> I'm currently debugging this issue and will have an update soon(-ish).
> > 
> > I have a patch set to have the kernel automatically rescan the device
> > when the ALUA state changes to an ACTIVE state, if it couldn't read
> > capacity when the device was initially probed.  I've had it for a while,
> > but I haven't had *any* response from the vendor if it actually works
> > with their product, so I haven't posted it to the list for review yet.
> > 
> Please hold off that patchset.

Sure.  It was really meant to be an RFC anyway.  I didn't want to
take up anyone's time unless it was a viable solution.

We talked a bit about having the kernel automatically update device
attributes at LSF back in March, this was a step towards that.
It implemented a notification mechanism so lower layers (e.g. ALUA
device handler) could propagate status changes up to upper layers
(e.g. sd device class).

> 
> I've posted the ALUA update patchset a while ago, and are working on
> including the suggestions from hch.
> 
> Please check if that patchset fixes the issue.

Will do, it's on my to-do list as soon as we get past a bunch of
other major stuff in the near term.

> 
> Additionally, I've got some patches for lio-target which will blank
> out the READ CAPACITY command when in standby; with that one has an
> easy testbed for this kind of issues.
> 
> > I did point out to them that the T10 spec does not *prohibit* supporting
> > the READ CAPACITY command in the ALUA standby state, which would avoid
> > the problem, and is what other vendors seem to do.  However, they then
> > raised the issue that if the capacity changes in the standby state then
> > they should be generating the capacity changed UA, etc and you can sort
> > of see their point of why this gets complicated.
> > 
> Which is actually not true. The capacity did _not_ change, it's just
> the command which isn't supported. If the command was supported and
> would have reported a size of '0' in standby _then_ it would have
> been a capacity change. But that's not the case here.

Yes, their argument was really more theoretical, in that "if we tell
you about the capacity in standby, we have to tell you when it changes
in standby" and they didn't want to implement that complexity in their
device server.

There's an interesting, somewhat-related issue I've come across with
iSCSI storage, when an event happens while the connection is not
established (i.e. link down, or logged out for some reason).  The T10
spec says that UAs are supposed to be reported on the I-T nexuses,


> 
> Cheers,
> 
> Hannes



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


Re: [PATCH] scsi: retry MODE SENSE on unit attention

2015-06-12 Thread Ewan Milne
On Fri, 2015-06-12 at 08:27 +0200, Hannes Reinecke wrote:
> On 06/11/2015 05:07 PM, Ewan Milne wrote:
> > On Thu, 2015-06-11 at 13:01 +0200, Hannes Reinecke wrote:
> >> The 'sd' driver is calling scsi_mode_sense() to figure out
> >> internal details. But scsi_mode_sense() never checks for
> >> any pending unit attentions, so we're getting annoying error
> >> messages like:
> >>
> >> MODE SENSE: unimplemented page/subpage: 0x00/0x00
> >>
> >> and a possible wrong decision for device cache handling.
> >>
> >> Signed-off-by: Hannes Reinecke 
> >> ---
> >>  drivers/scsi/scsi_lib.c | 7 ++-
> >>  1 file changed, 6 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> >> index 2428d96..d7915c8 100644
> >> --- a/drivers/scsi/scsi_lib.c
> >> +++ b/drivers/scsi/scsi_lib.c
> >> @@ -2423,7 +2423,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, 
> >> int modepage,
> >>unsigned char cmd[12];
> >>int use_10_for_ms;
> >>int header_length;
> >> -  int result;
> >> +  int result, retry_count = retries;
> >>struct scsi_sense_hdr my_sshdr;
> >>  
> >>memset(data, 0, sizeof(*data));
> >> @@ -2502,6 +2502,11 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, 
> >> int modepage,
> >>data->block_descriptor_length = buffer[3];
> >>}
> >>data->header_length = header_length;
> >> +  } else if ((status_byte(result) == CHECK_CONDITION) &&
> >> + scsi_sense_valid(sshdr) &&
> >> + sshdr->sense_key == UNIT_ATTENTION && retry_count) {
> >> +  retry_count--;
> >> +  goto retry;
> >>}
> >>  
> >>return result;
> > 
> > Great, but shouldn't we be doing this more generally?  What about
> > scsi_mode_select()?
> > 
> I haven't seen any issues with scsi_mode_select() as of now, so I
> didn't do anything about this :-)
> 
> > (And, with the number of status changes that can get reported by
> >  UAs, we might want to think about increasing the retry count on
> >  these commands up from 3 at some point.)
> > 
> Hmm. _Actually_, we're not getting _more_ UAs (neither the number
> nor the situation at which UAs are being send has changed).
> It's just that we're trying to _use_ UAs so these things pop up.
> But yeah, raising the number or retries to eg 5 is probably a good idea.

Yeah, or maybe add a time limit to we don't drag out the boot time.
We can do this later, though, I'm fine with your patch as it is.

> 
> > Reviewed-by: Ewan D. Milne 
> > 
> Cheers,
> 
> Hannes


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


Re: [PATCH] scsi: retry MODE SENSE on unit attention

2015-06-11 Thread Ewan Milne
On Thu, 2015-06-11 at 13:01 +0200, Hannes Reinecke wrote:
> The 'sd' driver is calling scsi_mode_sense() to figure out
> internal details. But scsi_mode_sense() never checks for
> any pending unit attentions, so we're getting annoying error
> messages like:
> 
> MODE SENSE: unimplemented page/subpage: 0x00/0x00
> 
> and a possible wrong decision for device cache handling.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/scsi_lib.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 2428d96..d7915c8 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -2423,7 +2423,7 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int 
> modepage,
>   unsigned char cmd[12];
>   int use_10_for_ms;
>   int header_length;
> - int result;
> + int result, retry_count = retries;
>   struct scsi_sense_hdr my_sshdr;
>  
>   memset(data, 0, sizeof(*data));
> @@ -2502,6 +2502,11 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int 
> modepage,
>   data->block_descriptor_length = buffer[3];
>   }
>   data->header_length = header_length;
> + } else if ((status_byte(result) == CHECK_CONDITION) &&
> +scsi_sense_valid(sshdr) &&
> +sshdr->sense_key == UNIT_ATTENTION && retry_count) {
> + retry_count--;
> + goto retry;
>   }
>  
>   return result;

Great, but shouldn't we be doing this more generally?  What about
scsi_mode_select()?

(And, with the number of status changes that can get reported by
 UAs, we might want to think about increasing the retry count on
 these commands up from 3 at some point.)

Reviewed-by: Ewan D. Milne 


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


Re: [PATCH] scsi: Add ALUA state change UA handling

2015-06-11 Thread Ewan Milne
On Thu, 2015-06-11 at 13:07 +0200, Hannes Reinecke wrote:
> Log the ALUA state change unit attention correctly with
> the message log and emit an event to allow user-space
> tools to react to it.
> 
> Signed-off-by: Hannes Reinecke 
> ---
>  drivers/scsi/scsi_error.c  | 4 
>  drivers/scsi/scsi_lib.c| 4 
>  include/scsi/scsi_device.h | 1 +
>  3 files changed, 9 insertions(+)
> 
> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index c95a4e9..ad32bc0 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -421,6 +421,10 @@ static void scsi_report_sense(struct scsi_device *sdev,
>   evt_type = SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED;
>   sdev_printk(KERN_WARNING, sdev,
>   "Mode parameters changed");
> + } else if (sshdr->asc == 0x2a && sshdr->ascq == 0x06) {
> + evt_type = SDEV_EVT_ALUA_STATE_CHANGE_REPORTED;
> + sdev_printk(KERN_WARNING, sdev,
> + "ALUA state has changed");

Would you mind changing this to "Asymmetic access state changed",
since that is the actual text in the T10 spec?

>   } else if (sshdr->asc == 0x2a && sshdr->ascq == 0x09) {
>   evt_type = SDEV_EVT_CAPACITY_CHANGE_REPORTED;
>   sdev_printk(KERN_WARNING, sdev,
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index b1a2631..2428d96 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -2698,6 +2698,9 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
> struct scsi_event *evt)
>   case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
>   envp[idx++] = "SDEV_UA=CAPACITY_DATA_HAS_CHANGED";
>   break;
> + case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
> + envp[idx++] = "SDEV_UA=ALUA_STATE_HAS_CHANGED";

And could you change this to "ASYMMETRIC_ACCESS_STATE_HAS_CHANGED"?

> + break;
>   case SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED:
>  envp[idx++] = "SDEV_UA=THIN_PROVISIONING_SOFT_THRESHOLD_REACHED";
>   break;
> @@ -2807,6 +2810,7 @@ struct scsi_event *sdev_evt_alloc(enum 
> scsi_device_event evt_type,
>   case SDEV_EVT_MEDIA_CHANGE:
>   case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
>   case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
> + case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
>   case SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED:
>   case SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED:
>   case SDEV_EVT_LUN_CHANGE_REPORTED:
> diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
> index a4c9336..5d7553f 100644
> --- a/include/scsi/scsi_device.h
> +++ b/include/scsi/scsi_device.h
> @@ -53,6 +53,7 @@ enum scsi_device_state {
>  enum scsi_device_event {
>   SDEV_EVT_MEDIA_CHANGE   = 1,/* media has changed */
>   SDEV_EVT_INQUIRY_CHANGE_REPORTED,   /* 3F 03  UA reported */
> + SDEV_EVT_ALUA_STATE_CHANGE_REPORTED,/* 2A 06  UA reported */
>   SDEV_EVT_CAPACITY_CHANGE_REPORTED,  /* 2A 09  UA reported */
>   SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED,   /* 38 07  UA reported */
>   SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED,/* 2A 01  UA reported */

Seems like a good idea.  As I mentioned yesterday, I have a patch set
that rescans the device when the ALUA state transitions to an ACTIVE
state, if the capacity could not be obtained when the device was
previously probed.  This could be made more generalized, too.
But I don't have the HW to test it, and I'm waiting for the vendor
to get back to me.

Reviewed-by: Ewan D. Milne 


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


Re: [dm-devel] ALUA - rescan device capacity on zero sized block devices

2015-06-10 Thread Ewan Milne
On Mon, 2015-04-20 at 07:58 +0200, Hannes Reinecke wrote:
> On 04/19/2015 12:56 AM, Christophe Varoqui wrote:
> > About five years ago, we faced a somewhat simular issue with
> > Symmetrix arrays, where the replicated LU of a SRDF pair (R2) was
> > flagged read-only by the kernel upon discovery. Splitting the pair
> > with a symcli command  made the LU read-write from the array
> > controller point of view, but the Linux kernel would not promote it
> > read-write dynamically.
> > 
> > I don't know if the Symmetrix array also use a unit attention to
> > signal the change to the initiators. If it does, it might be worth
> > trying to address both the 3par peer persistance and the Symmetrix
> > SRDF situations.
> > 
> > On the other hand, if the SRDF R2 rw promotion issue has been fixed
> > since, the patch might give guidance about where/how to plug the
> > 3par peer persistance ghost path rescans.
> > 
> It's not only that; if you are faced with LUNs in standby even the
> kernel wouldn't detect them properly.
> 
> I'm currently debugging this issue and will have an update soon(-ish).

I have a patch set to have the kernel automatically rescan the device
when the ALUA state changes to an ACTIVE state, if it couldn't read
capacity when the device was initially probed.  I've had it for a while,
but I haven't had *any* response from the vendor if it actually works
with their product, so I haven't posted it to the list for review yet.

I did point out to them that the T10 spec does not *prohibit* supporting
the READ CAPACITY command in the ALUA standby state, which would avoid
the problem, and is what other vendors seem to do.  However, they then
raised the issue that if the capacity changes in the standby state then
they should be generating the capacity changed UA, etc and you can sort
of see their point of why this gets complicated.

-Ewan

> 
> Cheers,
> 
> Hannes
> -- 
> Dr. Hannes Reinecke  zSeries & Storage
> h...@suse.de +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)
> 
> --
> dm-devel mailing list
> dm-de...@redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel


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


Re: [PATCH] scsi_transport_fc: Add support for 25Gbit speed

2015-04-09 Thread Ewan Milne
On Thu, 2015-04-02 at 15:50 -0400, James Smart wrote:
> Add FC transport support for 25Gbit speed
> 
> Signed-off-by: James Smart 
> ---
>  drivers/scsi/scsi_transport_fc.c | 1 +
>  include/scsi/scsi_transport_fc.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/scsi/scsi_transport_fc.c 
> b/drivers/scsi/scsi_transport_fc.c
> index 5d6f348..24eaaf6 100644
> --- a/drivers/scsi/scsi_transport_fc.c
> +++ b/drivers/scsi/scsi_transport_fc.c
> @@ -265,6 +265,7 @@ static const struct {
>   { FC_PORTSPEED_40GBIT,  "40 Gbit" },
>   { FC_PORTSPEED_50GBIT,  "50 Gbit" },
>   { FC_PORTSPEED_100GBIT, "100 Gbit" },
> + { FC_PORTSPEED_25GBIT,  "25 Gbit" },
>   { FC_PORTSPEED_NOT_NEGOTIATED,  "Not Negotiated" },
>  };
>  fc_bitfield_name_search(port_speed, fc_port_speed_names)
> diff --git a/include/scsi/scsi_transport_fc.h 
> b/include/scsi/scsi_transport_fc.h
> index 007a0bc..784bc2c 100644
> --- a/include/scsi/scsi_transport_fc.h
> +++ b/include/scsi/scsi_transport_fc.h
> @@ -135,6 +135,7 @@ enum fc_vport_state {
>  #define FC_PORTSPEED_40GBIT  0x100
>  #define FC_PORTSPEED_50GBIT  0x200
>  #define FC_PORTSPEED_100GBIT 0x400
> +#define FC_PORTSPEED_25GBIT  0x800
>  #define FC_PORTSPEED_NOT_NEGOTIATED  (1 << 15) /* Speed not established */
>  
>  /*

Reviewed-by: Ewan D. Milne 


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


Re: iSCSI regression with linux 3.9 and 4.0

2015-03-23 Thread Ewan Milne
On Mon, 2015-03-23 at 09:53 +0100, Christian Hesse wrote:
> 
> I reverted these two commits:
> 
> commit 3a9794d32984b67a6d8992226918618f0e51e5d5
> Author: Brian King 
> Date:   Thu Jan 29 15:54:40 2015 -0600
> 
> sd: Fix max transfer length for 4k disks
> 
> commit bcdb247c6b6a1f3e72b9b787b73f47dd509d17ec
> Author: Martin K. Petersen 
> Date:   Tue Jun 3 18:45:51 2014 -0400
> 
> sd: Limit transfer length
>  
> iSCSI device still fails, max_sectors_kb is still set to 32767. Looks like
> there is another change that introduced the regression.

OK, as Mike Christie suggested, see if you can get a wireshark/tcpdump
trace with both the 3.18 (working) and 3.19 (failing) kernels.

-Ewan


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


Re: [PATCH] scsi: sd: add a capacity_override attribute

2015-03-20 Thread Ewan Milne
On Fri, 2015-03-20 at 12:03 -0400, Alan Stern wrote:
> On Fri, 20 Mar 2015, Ewan Milne wrote:
> 
> > On Fri, 2015-03-20 at 11:19 -0400, Alan Stern wrote:
> > > On Fri, 20 Mar 2015, Ewan Milne wrote:
> > > 
> > > > On Tue, 2015-03-17 at 14:08 -0400, Alan Stern wrote:
> > > > > This patch provides a sysfs interface allowing users to override the
> > > > > capacity of a SCSI disk.  This will help in situations where a buggy
> > > > > USB-SATA adapter fails to support READ CAPACITY(16) and reports only
> > > > > the low 32 bits of the capacity in its READ CAPACITY(10) reply.  For
> > > > > an example, see this thread:
> > > > > 
> > > > >   http://marc.info/?l=linux-scsi&m=140908235510961&w=2
> > > > > 
> > > > > The interface is awkward because it requires the user to tell the
> > > > > system to re-read the disk's partition table afterward, but at least
> > > > > it provides a way to handle deficient hardware.
> > > > 
> > > > I think that it is confusing that writing into the capacity_override
> > > > sysfs node does not get immediately reflected in the gendisk structure.
> > > > Would it hurt to call sd_revalidate_disk() after the value is changed
> > > > in capacity_override_store()?
> > > 
> > > It wouldn't hurt, but it wouldn't help much either.
> > > 
> > > sd_revalidate_disk() might cause the new size to show up in the
> > > gendisk structure, but it would not cause the partition table to be
> > > parsed again.  That's the real reason for doing this -- when a drive
> > > seems to have fewer blocks than it really does, partitions that extend
> > > beyond the "end" of the drive are rejected.
> > 
> > OK, I see.
> > 
> > > 
> > > > The thing is, if someone overrides the capacity but does not do anything
> > > > right away to revalidate the disk, it could change at some arbitrary
> > > > time in the future when the revalidation happens for some other reason.
> > > 
> > > That's why the documentation says that users must force the system to 
> > > re-read the partition table after writing the sysfs attribute.  In my 
> > > tests, doing that caused a revalidation.
> > > 
> > > Are you saying that could have been a coincidence?  It's possible -- I 
> > > don't understand the design of the block layer.
> > 
> > No, I think that re-reading the partition table will revalidate.  What I
> > was concerned about is some unsuspecting user writing to the
> > capacity_override sysfs node, observing that it didn't seem to do
> > anything, and being surprised when it changed later.  (I've seen some
> > issues with multipath, for example, which will stop using a path if the
> > capacity changes.)  I guess it's a "principle of least surprise" thing.
> > 
> > Having said that, if this is what is needed to make the devices work...
> > 
> > Reviewed-by: Ewan D. Milne 
> 
> Thanks.  I don't _mind_ adding an sd_revalidate_disk() call if you 
> think it will improve the patch.  What's your suggestion?
> 

If that does not cause the partition table to be updated, then it
doesn't solve your problem, so I'd leave it the way it is, for now.

-Ewan

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


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


Re: iSCSI regression with linux 3.9 and 4.0

2015-03-20 Thread Ewan Milne
On Fri, 2015-03-20 at 16:24 +0100, Christian Hesse wrote:
> Ewan Milne  on Fri, 2015/03/20 11:04:
> > On Fri, 2015-03-20 at 15:31 +0100, Christian Hesse wrote:
> > > Ewan Milne  on Fri, 2015/03/20 09:51:
> > > > On Fri, 2015-03-20 at 13:57 +0100, Christian Hesse wrote:
> > > > > Hello everybody!
> > > > > 
> > > > > I reported this issue at LKML [0] but received no answer. Hopefully
> > > > > linux-scsi is a better place...
> > > > > 
> > > > > Beginning with linux 3.19 I see an iSCSI regressen. This works
> > > > > perfectly with linux 3.18.x (tested with 3.18.6) and before. Effected
> > > > > kernels I tested are 3.19.0, 3.19.2 and 4.0rc4.r199.gb314aca.
> > > > > 
> > > > > The logs tell the story:
> > > > > 
> > > > > [snip log]
> > > > > 
> > > > > [0] https://lkml.org/lkml/2015/2/19/91
> > > > 
> > > > Sense key 0x5 ASC/ASCQ 0x24 0x00 is ILLEGAL REQUEST, INVALID FIELD IN
> > > > CDB.  The CDB was 2A 00 34 5B 07 FF 00 2F 88 00, which is a WRITE_10
> > > > to LBA 878381055 with a length of 12168 blocks (a little less than 6MB).
> > > > It looks like this is within the reported capacity of the device, and
> > > > there are no other bits set in the CDB.
> > > > 
> > > > Looks like you could get this error if RWWP (reject without write
> > > > protection) is set in the control mode page.  I don't see any messages
> > > > about the protection type, though.  What does sysfs report?
> > > 
> > > Is that what you are interested in?
> > > 
> > > # cat protection_mode protection_type 
> > > none
> > > 0
> > > 
> > > In case it matters: The iSCSI device is LUKS encrypted, that is why device
> > > mapper shows up.
> > > 
> > > I removed the discard option from filesystem's default mount option, but
> > > that brings no difference except the message is not printed.
> > 
> > It is most likely the device that is returning the error, there is a
> > place in the iSCSI Initiator that generates an ILLEGAL REQUEST sense,
> > but it is not the same ASC/ASCQ.
> > 
> > There was this change:
> > 
> > commit bcdb247c6b6a1f3e72b9b787b73f47dd509d17ec
> > Author: Martin K. Petersen 
> > Date:   Tue Jun 3 18:45:51 2014 -0400
> > 
> > sd: Limit transfer length
> > 
> > Until now the per-command transfer length has exclusively been gated by
> > the max_sectors parameter in the scsi_host template. Given that the size
> > of this parameter has been bumped to an unsigned int we have to be
> > careful not to exceed the target device's capabilities.
> > 
> > If the if the device specifies a Maximum Transfer Length in the Block
> > Limits VPD we'll use that value. Otherwise we'll use 0x for
> > devices that have use_16_for_rw set and 0x for the rest. We then
> > combine the chosen disk limit with max_sectors in the host template. The
> > smaller of the two will be used to set the max_hw_sectors queue limit.
> > 
> > Signed-off-by: Martin K. Petersen 
> > Reviewed-by: Ewan D. Milne 
> > Signed-off-by: Christoph Hellwig 
> > 
> > What is the value of max_sectors_kb and queue_max_sectors_kb in sysfs
> > for the device?  Is it different than what is reported on 3.18?
> 
> I found 'max_sectors_kb' which is inside in directory called 'queue'. Is that
> the value you asked for?
> 
> for 4.0 git:
> 
> # cat max_sectors_kb
> 32767

If you change max_sectors_kb to a lower value (e.g. 512) can you get the
device to work?

There is a max_hw_sectors_kb value but you can't change it.  Is it
32768 also for 4.0?

Your device reports a maximum transfer length of 2^32-1 blocks but
I suspect that it might not be actually able to do that.  I don't see
what else would be causing the error.  Maybe there is a transport
limitation that is getting in the way?

-Ewan

> 
> for 3.18.6:
> 
> # cat max_sectors_kb
> 512
> 
> > Does your target support the Block Limits VPD (page B0)?  (i.e. can
> > you run "sg_inq /dev/sda -p bl" from the sg3_utils package?)
> 
> This does not differ for different kernels. I think this is expected.
> 
> # sg_inq /dev/sdb -p bl
> VPD INQUIRY: Block limits page (SBC)
>   Maximum compare and write length: 1 blocks
>   Optimal transfer length granularity: 1 blocks
>   Maximum transfer length: 4294967295 blocks
>   Optimal transfer length: 4294967295 blocks
>   Maximum prefetch, xdread, xdwrite transfer length: 0 blocks
>   Maximum unmap LBA count: 8388607
>   Maximum unmap block descriptor count: 1
>   Optimal unmap granularity: 16383
>   Unmap granularity alignment valid: 0
>   Unmap granularity alignment: 0
>   Maximum write same length: 0x blocks
>   Maximum atomic transfer length: 0
>   Atomic alignment: 0
>   Atomic transfer length granularity: 0


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


Re: [PATCH] scsi: sd: add a capacity_override attribute

2015-03-20 Thread Ewan Milne
On Fri, 2015-03-20 at 11:19 -0400, Alan Stern wrote:
> On Fri, 20 Mar 2015, Ewan Milne wrote:
> 
> > On Tue, 2015-03-17 at 14:08 -0400, Alan Stern wrote:
> > > This patch provides a sysfs interface allowing users to override the
> > > capacity of a SCSI disk.  This will help in situations where a buggy
> > > USB-SATA adapter fails to support READ CAPACITY(16) and reports only
> > > the low 32 bits of the capacity in its READ CAPACITY(10) reply.  For
> > > an example, see this thread:
> > > 
> > >   http://marc.info/?l=linux-scsi&m=140908235510961&w=2
> > > 
> > > The interface is awkward because it requires the user to tell the
> > > system to re-read the disk's partition table afterward, but at least
> > > it provides a way to handle deficient hardware.
> > 
> > I think that it is confusing that writing into the capacity_override
> > sysfs node does not get immediately reflected in the gendisk structure.
> > Would it hurt to call sd_revalidate_disk() after the value is changed
> > in capacity_override_store()?
> 
> It wouldn't hurt, but it wouldn't help much either.
> 
> sd_revalidate_disk() might cause the new size to show up in the
> gendisk structure, but it would not cause the partition table to be
> parsed again.  That's the real reason for doing this -- when a drive
> seems to have fewer blocks than it really does, partitions that extend
> beyond the "end" of the drive are rejected.

OK, I see.

> 
> > The thing is, if someone overrides the capacity but does not do anything
> > right away to revalidate the disk, it could change at some arbitrary
> > time in the future when the revalidation happens for some other reason.
> 
> That's why the documentation says that users must force the system to 
> re-read the partition table after writing the sysfs attribute.  In my 
> tests, doing that caused a revalidation.
> 
> Are you saying that could have been a coincidence?  It's possible -- I 
> don't understand the design of the block layer.

No, I think that re-reading the partition table will revalidate.  What I
was concerned about is some unsuspecting user writing to the
capacity_override sysfs node, observing that it didn't seem to do
anything, and being surprised when it changed later.  (I've seen some
issues with multipath, for example, which will stop using a path if the
capacity changes.)  I guess it's a "principle of least surprise" thing.

Having said that, if this is what is needed to make the devices work...

Reviewed-by: Ewan D. Milne 

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


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


Re: iSCSI regression with linux 3.9 and 4.0

2015-03-20 Thread Ewan Milne
On Fri, 2015-03-20 at 11:04 -0400, Ewan Milne wrote:
> Does your target support the Block Limits VPD (page B0)?  (i.e. can
> you run "sg_inq /dev/sda -p bl" from the sg3_utils package?)
> 

I meant /dev/sdb, sorry.


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


Re: iSCSI regression with linux 3.9 and 4.0

2015-03-20 Thread Ewan Milne
On Fri, 2015-03-20 at 15:31 +0100, Christian Hesse wrote:
> Ewan Milne  on Fri, 2015/03/20 09:51:
> > On Fri, 2015-03-20 at 13:57 +0100, Christian Hesse wrote:
> > > Hello everybody!
> > > 
> > > I reported this issue at LKML [0] but received no answer. Hopefully
> > > linux-scsi is a better place...
> > > 
> > > Beginning with linux 3.19 I see an iSCSI regressen. This works perfectly
> > > with linux 3.18.x (tested with 3.18.6) and before. Effected kernels I
> > > tested are 3.19.0, 3.19.2 and 4.0rc4.r199.gb314aca.
> > > 
> > > The logs tell the story:
> > > 
> > > Feb 19 11:26:49 thebe kernel: scsi host6: iSCSI Initiator over TCP/IP
> > > Feb 19 11:26:49 thebe kernel: scsi 6:0:0:0: Direct-Access QNAP
> > > iSCSI Storage4.0  PQ: 0 ANSI: 5 Feb 19 11:26:49 thebe kernel: sd
> > > 6:0:0:0: [sdb] 1073741824 512-byte logical blocks: (549 GB/512 GiB) Feb
> > > 19 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] Write Protect is off Feb 19
> > > 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] Mode Sense: 2f 00 00 00 Feb 19
> > > 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] Write cache: disabled, read
> > > cache: enabled, doesn't support DPO or FUA Feb 19 11:26:49 thebe kernel:
> > > sdb: unknown partition table Feb 19 11:26:49 thebe kernel: sd 6:0:0:0:
> > > [sdb] Attached SCSI disk Feb 19 11:26:49 thebe iscsid[10804]:
> > > Connection1:0 to [target:
> > > iqn.2004-04.com.qnap:ts-859:iscsi.xxx.c40a18, portal:
> > > xx.xx.xx.xx,3260] through [iface: default] is operational now Feb 19
> > > 11:26:57 thebe kernel:  sdb: unknown partition table Feb 19 11:28:20
> > > thebe kernel: EXT4-fs (dm-8): mounting with "discard" option, but the
> > > device does not support discard Feb 19 11:28:20 thebe kernel: EXT4-fs
> > > (dm-8): mounted filesystem with ordered data mode. Opts: (null) Feb 19
> > > 11:28:24 thebe kernel: sd 6:0:0:0: [sdb] UNKNOWN Result: hostbyte=0x00
> > > driverbyte=0x08 Feb 19 11:28:24 thebe kernel: sd 6:0:0:0: [sdb] Sense
> > > Key : 0x5 [current] Feb 19 11:28:24 thebe kernel: sd 6:0:0:0: [sdb]
> > > ASC=0x24 ASCQ=0x0 Feb 19 11:28:24 thebe kernel: sd 6:0:0:0: [sdb] CDB:
> > > Feb 19 11:28:24 thebe kernel: cdb[0]=0x2a: 2a 00 34 5b 07 ff 00 2f 88 00
> > > Feb 19 11:28:24 thebe kernel: blk_update_request: critical target error,
> > > dev sdb, sector 878381055 Feb 19 11:28:24 thebe kernel: EXT4-fs warning
> > > (device dm-8): ext4_end_bio:317: I/O error -121 writing to inode 33196503
> > > (offset 8388608 size 7278592 starting block 108749056) Feb 19 11:28:24
> > > thebe kernel: Buffer I/O error on device dm-8, logical block 108749056
> > > Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical
> > > block 108749057 Feb 19 11:28:24 thebe kernel: Buffer I/O error on device
> > > dm-8, logical block 108749058 Feb 19 11:28:24 thebe kernel: Buffer I/O
> > > error on device dm-8, logical block 108749059 Feb 19 11:28:24 thebe
> > > kernel: Buffer I/O error on device dm-8, logical block 108749060 Feb 19
> > > 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block
> > > 108749061 Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8,
> > > logical block 108749062 Feb 19 11:28:24 thebe kernel: Buffer I/O error on
> > > device dm-8, logical block 108749063 Feb 19 11:28:24 thebe kernel: Buffer
> > > I/O error on device dm-8, logical block 108749064 Feb 19 11:28:24 thebe
> > > kernel: Buffer I/O error on device dm-8, logical block 108749065 Feb 19
> > > 11:28:24 thebe kernel: EXT4-fs warning (device dm-8): ext4_end_bio:317:
> > > I/O error -121 writing to inode 33196503 (offset 8388608 size 7278592
> > > starting block 108749312) Feb 19 11:28:24 thebe kernel: EXT4-fs warning
> > > (device dm-8): ext4_end_bio:317: I/O error -121 writing to inode 33196503
> > > (offset 8388608 size 7278592 starting block 108749568) Feb 19 11:28:24
> > > thebe kernel: EXT4-fs warning (device dm-8): ext4_end_bio:317: I/O error
> > > -121 writing to inode 33196503 (offset 8388608 size 7278592 starting
> > > block 108749824) Feb 19 11:28:24 thebe kernel: EXT4-fs warning (device
> > > dm-8): ext4_end_bio:317: I/O error -121 writing to inode 33196503 (offset
> > > 8388608 size 7278592 starting block 108750080) Feb 19 11:28:24 thebe
> > > kernel: EXT4-fs warning (device dm-8): ext4_end_bio:317: I/O error -121
> > > writing to inode 33196503 (offset 8388608 size 7278592 starting block
> > > 108750336) Feb 19 11:29:10 thebe kernel: sd 6:0:0:

Re: [PATCH] scsi: sd: add a capacity_override attribute

2015-03-20 Thread Ewan Milne
On Tue, 2015-03-17 at 14:08 -0400, Alan Stern wrote:
> This patch provides a sysfs interface allowing users to override the
> capacity of a SCSI disk.  This will help in situations where a buggy
> USB-SATA adapter fails to support READ CAPACITY(16) and reports only
> the low 32 bits of the capacity in its READ CAPACITY(10) reply.  For
> an example, see this thread:
> 
>   http://marc.info/?l=linux-scsi&m=140908235510961&w=2
> 
> The interface is awkward because it requires the user to tell the
> system to re-read the disk's partition table afterward, but at least
> it provides a way to handle deficient hardware.

I think that it is confusing that writing into the capacity_override
sysfs node does not get immediately reflected in the gendisk structure.
Would it hurt to call sd_revalidate_disk() after the value is changed
in capacity_override_store()?

The thing is, if someone overrides the capacity but does not do anything
right away to revalidate the disk, it could change at some arbitrary
time in the future when the revalidation happens for some other reason.

-Ewan

> 
> Signed-off-by: Alan Stern 
> CC: Dale R. Worley 
> 
> ---
> 
> 
> [as1777]
> 
> 
>  Documentation/ABI/testing/sysfs-class-scsi_disk |   19 
>  drivers/scsi/sd.c   |   37 
> 
>  drivers/scsi/sd.h   |1 
>  3 files changed, 57 insertions(+)
> 
> Index: usb-4.0/Documentation/ABI/testing/sysfs-class-scsi_disk
> ===
> --- /dev/null
> +++ usb-4.0/Documentation/ABI/testing/sysfs-class-scsi_disk
> @@ -0,0 +1,19 @@
> +What:
> /sys/class/scsi_disk/HOST:CHANNEL:TARGET:LUN/capacity_override
> +Date:March 2015
> +KernelVersion:   4.1
> +Contact: Alan Stern 
> +Description:
> + This file provides a way for users to override the
> + automatically determined disk capacity.  For example, some
> + buggy USB-SATA adapters report only the low 32 bits of a
> + drive's block count, resulting in a calculated capacity
> + value that is the actual capacity modulo 2 TB.
> +
> + After the correct capacity (in native-size blocks -- often
> + 512 bytes per block but sometimes 4096) is written to this
> + file, the user must tell the system to re-read the disk's
> + partition table by running the command:
> +
> + /usr/sbin/blockdev --rereadpt /dev/sdX
> +
> + where X is the disk's drive letter.
> Index: usb-4.0/drivers/scsi/sd.h
> ===
> --- usb-4.0.orig/drivers/scsi/sd.h
> +++ usb-4.0/drivers/scsi/sd.h
> @@ -66,6 +66,7 @@ struct scsi_disk {
>   struct gendisk  *disk;
>   atomic_topeners;
>   sector_tcapacity;   /* size in 512-byte sectors */
> + sector_tcapacity_override;  /* in native-size blocks */
>   u32 max_xfer_blocks;
>   u32 max_ws_blocks;
>   u32 max_unmap_blocks;
> Index: usb-4.0/drivers/scsi/sd.c
> ===
> --- usb-4.0.orig/drivers/scsi/sd.c
> +++ usb-4.0/drivers/scsi/sd.c
> @@ -477,6 +477,35 @@ max_write_same_blocks_store(struct devic
>  }
>  static DEVICE_ATTR_RW(max_write_same_blocks);
>  
> +static ssize_t
> +capacity_override_show(struct device *dev, struct device_attribute *attr,
> + char *buf)
> +{
> + struct scsi_disk *sdkp = to_scsi_disk(dev);
> +
> + return sprintf(buf, "%llu\n",
> + (unsigned long long) sdkp->capacity_override);
> +}
> +
> +static ssize_t
> +capacity_override_store(struct device *dev, struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct scsi_disk *sdkp = to_scsi_disk(dev);
> + unsigned long long cap;
> + int err;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EACCES;
> +
> + err = kstrtoull(buf, 10, &cap);
> + if (err)
> + return err;
> + sdkp->capacity_override = cap;
> + return count;
> +}
> +static DEVICE_ATTR_RW(capacity_override);
> +
>  static struct attribute *sd_disk_attrs[] = {
>   &dev_attr_cache_type.attr,
>   &dev_attr_FUA.attr,
> @@ -489,6 +518,7 @@ static struct attribute *sd_disk_attrs[]
>   &dev_attr_provisioning_mode.attr,
>   &dev_attr_max_write_same_blocks.attr,
>   &dev_attr_max_medium_access_timeouts.attr,
> + &dev_attr_capacity_override.attr,
>   NULL,
>  };
>  ATTRIBUTE_GROUPS(sd_disk);
> @@ -2152,6 +2182,13 @@ sd_read_capacity(struct scsi_disk *sdkp,
>   struct scsi_device *sdp = sdkp->device;
>   sector_t old_capacity = sdkp->capacity;
>  
> + /* Did the user override the reported capacity? */
> + if (!sdkp->first_scan && sdkp->capacity_override) {
> + sector_

Re: iSCSI regression with linux 3.9 and 4.0

2015-03-20 Thread Ewan Milne
On Fri, 2015-03-20 at 13:57 +0100, Christian Hesse wrote:
> Hello everybody!
> 
> I reported this issue at LKML [0] but received no answer. Hopefully
> linux-scsi is a better place...
> 
> Beginning with linux 3.19 I see an iSCSI regressen. This works perfectly with
> linux 3.18.x (tested with 3.18.6) and before. Effected kernels I tested are
> 3.19.0, 3.19.2 and 4.0rc4.r199.gb314aca.
> 
> The logs tell the story:
> 
> Feb 19 11:26:49 thebe kernel: scsi host6: iSCSI Initiator over TCP/IP
> Feb 19 11:26:49 thebe kernel: scsi 6:0:0:0: Direct-Access QNAP iSCSI 
> Storage4.0  PQ: 0 ANSI: 5
> Feb 19 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] 1073741824 512-byte logical 
> blocks: (549 GB/512 GiB)
> Feb 19 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] Write Protect is off
> Feb 19 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] Mode Sense: 2f 00 00 00
> Feb 19 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] Write cache: disabled, read 
> cache: enabled, doesn't support DPO or FUA
> Feb 19 11:26:49 thebe kernel:  sdb: unknown partition table
> Feb 19 11:26:49 thebe kernel: sd 6:0:0:0: [sdb] Attached SCSI disk
> Feb 19 11:26:49 thebe iscsid[10804]: Connection1:0 to [target: 
> iqn.2004-04.com.qnap:ts-859:iscsi.xxx.c40a18, portal: xx.xx.xx.xx,3260] 
> through [iface: default] is operational now
> Feb 19 11:26:57 thebe kernel:  sdb: unknown partition table
> Feb 19 11:28:20 thebe kernel: EXT4-fs (dm-8): mounting with "discard" option, 
> but the device does not support discard
> Feb 19 11:28:20 thebe kernel: EXT4-fs (dm-8): mounted filesystem with ordered 
> data mode. Opts: (null)
> Feb 19 11:28:24 thebe kernel: sd 6:0:0:0: [sdb] UNKNOWN Result: hostbyte=0x00 
> driverbyte=0x08
> Feb 19 11:28:24 thebe kernel: sd 6:0:0:0: [sdb] Sense Key : 0x5 [current]
> Feb 19 11:28:24 thebe kernel: sd 6:0:0:0: [sdb] ASC=0x24 ASCQ=0x0
> Feb 19 11:28:24 thebe kernel: sd 6:0:0:0: [sdb] CDB: 
> Feb 19 11:28:24 thebe kernel: cdb[0]=0x2a: 2a 00 34 5b 07 ff 00 2f 88 00
> Feb 19 11:28:24 thebe kernel: blk_update_request: critical target error, dev 
> sdb, sector 878381055
> Feb 19 11:28:24 thebe kernel: EXT4-fs warning (device dm-8): 
> ext4_end_bio:317: I/O error -121 writing to inode 33196503 (offset 8388608 
> size 7278592 starting block 108749056)
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749056
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749057
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749058
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749059
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749060
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749061
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749062
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749063
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749064
> Feb 19 11:28:24 thebe kernel: Buffer I/O error on device dm-8, logical block 
> 108749065
> Feb 19 11:28:24 thebe kernel: EXT4-fs warning (device dm-8): 
> ext4_end_bio:317: I/O error -121 writing to inode 33196503 (offset 8388608 
> size 7278592 starting block 108749312)
> Feb 19 11:28:24 thebe kernel: EXT4-fs warning (device dm-8): 
> ext4_end_bio:317: I/O error -121 writing to inode 33196503 (offset 8388608 
> size 7278592 starting block 108749568)
> Feb 19 11:28:24 thebe kernel: EXT4-fs warning (device dm-8): 
> ext4_end_bio:317: I/O error -121 writing to inode 33196503 (offset 8388608 
> size 7278592 starting block 108749824)
> Feb 19 11:28:24 thebe kernel: EXT4-fs warning (device dm-8): 
> ext4_end_bio:317: I/O error -121 writing to inode 33196503 (offset 8388608 
> size 7278592 starting block 108750080)
> Feb 19 11:28:24 thebe kernel: EXT4-fs warning (device dm-8): 
> ext4_end_bio:317: I/O error -121 writing to inode 33196503 (offset 8388608 
> size 7278592 starting block 108750336)
> Feb 19 11:29:10 thebe kernel: sd 6:0:0:0: [sdb] UNKNOWN Result: hostbyte=0x00 
> driverbyte=0x08
> Feb 19 11:29:10 thebe kernel: sd 6:0:0:0: [sdb] Sense Key : 0x5 [current]
> Feb 19 11:29:10 thebe kernel: sd 6:0:0:0: [sdb] ASC=0x24 ASCQ=0x0
> Feb 19 11:29:10 thebe kernel: sd 6:0:0:0: [sdb] CDB: 
> Feb 19 11:29:10 thebe kernel: cdb[0]=0x2a: 2a 00 20 44 89 17 00 20 50 00
> Feb 19 11:29:10 thebe kernel: blk_update_request: critical target error, dev 
> sdb, sector 541362455
> Feb 19 11:29:10 thebe kernel: Buffer I/O error on dev dm-8, logical block 
> 66621731, lost sync page write
> Feb 19 11:29:10 thebe kernel: Aborting journal on device dm-8-8.
> Feb 19 11:29:10 thebe kernel: EXT4-fs error (device dm-8): 
> ext4_journal_check_start:56: Detected aborted journal
> Feb 19 11:29:10 thebe kernel: EXT4-fs (dm-8): Remounting filesystem read-only
> Feb 19 11:29:20 thebe kernel: EXT4-fs error (device dm

  1   2   >