Re: PROBLEM: special sense code asc,ascq=04h,0Ch abort scsi scan in the middle

2013-10-16 Thread Hannes Reinecke
On 10/14/2013 05:24 PM, Steffen Maier wrote:
 On 10/14/2013 03:32 PM, Hannes Reinecke wrote:
 On 10/14/2013 03:18 PM, Hannes Reinecke wrote:
 On 10/14/2013 02:51 PM, Steffen Maier wrote:
 On 10/14/2013 01:13 PM, Hannes Reinecke wrote:
 On 10/13/2013 07:23 PM, Vaughan Cao wrote:
 [1.] One line summary of the problem:
 special sense code asc,ascq=04h,0Ch abort scsi scan in the middle

 [2.] Full description of the problem/report:
 For instance, storage represents 8 iscsi LUNs, however the LUN
 No.7
 is not well configured or has something wrong.
 Then messages received:
 kernel: scsi 5:0:0:0: Unexpected response from lun 7 while
 scanning, scan aborted
 Which will make LUN No.8 unavailable.
 It's confirmed that Windows and Solaris systems will continue the
 scan and make LUN No.1,2,3,4,5,6 and 8 available.

 Log snippet is as below:
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: scsi scan:
 INQUIRY pass 1 length 36
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: Send:
 0x8801e9bd4280
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: CDB:
 Inquiry: 12 00 00 00 24 00
 Aug 24 00:32:49 vmhodtest019 kernel: buffer =
 0x8801f71fc180, bufflen = 36, queuecommand 0xa00b99e7
 Aug 24 00:32:49 vmhodtest019 kernel: leaving scsi_dispatch_cmnd()
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: Done:
 0x8801e9bd4280 SUCCESS
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: Result:
 hostbyte=DID_OK driverbyte=DRIVER_OK
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: CDB:
 Inquiry: 12 00 00 00 24 00
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: Sense Key :
 Not Ready [current]
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: Add. Sense:
 Logical unit not accessible, target port in unavailable state
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:7: scsi host
 busy 1 failed 0
 Aug 24 00:32:49 vmhodtest019 kernel: 0 sectors total, 36 bytes
 done.
 Aug 24 00:32:49 vmhodtest019 kernel: scsi scan: INQUIRY failed
 with code 0x802
 Aug 24 00:32:49 vmhodtest019 kernel: scsi 5:0:0:0: Unexpected
 response from lun 7 while scanning, scan aborted

 According to scsi_report_lun_scan(), I found:
 Linux use an inquiry command to probe a lun according to the
 result
 of report_lun command.
 It assumes every probe cmd will get a legal result. Otherwise, it
 regards the whole peripheral not exist or dead.
 If the return of inquiry passes its legal checking and indicates
 'LUN not present', it won't break but also continue with the scan
 process.
 In the log, inquiry to LUN7 return a sense - asc,ascq=04h,0Ch
 (Logical unit not accessible, target port in unavailable state).
 And this is ignored, so scsi_probe_lun() returns -EIO and the
 scan
 process is aborted.

 I have two questions:
 1. Is it correct for hardware to return a sense 04h,0Ch to
 inquiry
 again, even after presenting this lun in responce to REPORT_LUN
 command?
 Yes, this is correct. 'REPORT LUNS' is supported in
 'Unavailable' state.

 2. Since windows and solaris can continue scan, is it
 reasonable for
 linux to do the same, even for a fault-tolerance purpose?

 Hmm. Yes, and no.

 _Actually_ this is an issue with the target, as it looks as if it
 will return the above sense code while sending an 'INQUIRY' to the
 device.
 SPC explicitely states that the INQUIRY command should _not_ fail
 for unavailable devices.
 But yeah, we probably should work around this issues.
 Nevertheless, please raise this issue with your array vendor.

 Please try the attached patch.

 Cheers,

 Hannes


  From b0e90778f012010c881f8bdc03bce63a36921b77 Mon Sep 17
 00:00:00 2001
 From: Hannes Reinecke h...@suse.de
 Date: Mon, 14 Oct 2013 13:11:22 +0200
 Subject: [PATCH] scsi_scan: continue report_lun_scan after error

 When scsi_probe_and_add_lun() fails in scsi_report_lun_scan() this
 does _not_ indicate that the entire target is done for.
 So continue scanning for the remaining devices.

 Signed-off-by: Hannes Reinecke h...@suse.de

 diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
 index 307a811..973a121 100644
 --- a/drivers/scsi/scsi_scan.c
 +++ b/drivers/scsi/scsi_scan.c
 @@ -1484,13 +1484,12 @@ static int scsi_report_lun_scan(struct
 scsi_target *starget, int bflags,
   lun, NULL, NULL, rescan, NULL);
   if (res == SCSI_SCAN_NO_RESPONSE) {
   /*
 - * Got some results, but now none, abort.
 + * Got some results, but now none, ignore.
*/
   sdev_printk(KERN_ERR, sdev,
   Unexpected response
 - from lun %d while scanning, scan
 - aborted\n, lun);
 -break;
 + from lun %d while scanning,
 + ignoring device\n, lun);
   }
   }
   }

 In LLDDs that do their own initiator based LUN masking (because
 the midlayer does not have this
 functionality to enable hardware virtualization 

[PATCH 0/5] Updates for tcm_loop

2013-10-16 Thread Hannes Reinecke
Hi Nic,

here are some updates to tcm_loop I've done during ALUA testing.
I've implemented a 'transport_state' attribute to simulate
transport failure and added command abort callbacks.

Hannes Reinecke (5):
  tcm_loop: Check for valid hba in tcm_loop_drop_nexus()
  tcm_loop: Implement transport offline
  tcm_loop: separate out tcm_loop_issue_tmr
  tcm_loop: TCQ and command abort support
  tcm_loop: Implement target reset

 drivers/target/loopback/tcm_loop.c | 233 +++--
 drivers/target/loopback/tcm_loop.h |   6 +
 include/target/target_core_base.h  |   1 +
 3 files changed, 204 insertions(+), 36 deletions(-)

-- 
1.7.12.4

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


[PATCH 3/5] tcm_loop: separate out tcm_loop_issue_tmr

2013-10-16 Thread Hannes Reinecke
No functional change.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/loopback/tcm_loop.c | 83 +++---
 include/target/target_core_base.h  |  1 +
 2 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/drivers/target/loopback/tcm_loop.c 
b/drivers/target/loopback/tcm_loop.c
index f81ebe4..7232976 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -245,41 +245,21 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, 
struct scsi_cmnd *sc)
  * Called from SCSI EH process context to issue a LUN_RESET TMR
  * to struct scsi_device
  */
-static int tcm_loop_device_reset(struct scsi_cmnd *sc)
+static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
+ struct tcm_loop_nexus *tl_nexus,
+ int lun, enum tcm_tmreq_table tmr)
 {
struct se_cmd *se_cmd = NULL;
-   struct se_portal_group *se_tpg;
struct se_session *se_sess;
+   struct se_portal_group *se_tpg;
struct tcm_loop_cmd *tl_cmd = NULL;
-   struct tcm_loop_hba *tl_hba;
-   struct tcm_loop_nexus *tl_nexus;
struct tcm_loop_tmr *tl_tmr = NULL;
-   struct tcm_loop_tpg *tl_tpg;
-   int ret = FAILED, rc;
-   /*
-* Locate the tcm_loop_hba_t pointer
-*/
-   tl_hba = *(struct tcm_loop_hba **)shost_priv(sc-device-host);
-   /*
-* Locate the tl_nexus and se_sess pointers
-*/
-   tl_nexus = tl_hba-tl_nexus;
-   if (!tl_nexus) {
-   pr_err(Unable to perform device reset without
-active I_T Nexus\n);
-   return FAILED;
-   }
-   se_sess = tl_nexus-se_sess;
-   /*
-* Locate the tl_tpg and se_tpg pointers from TargetID in sc-device-id
-*/
-   tl_tpg = tl_hba-tl_hba_tpgs[sc-device-id];
-   se_tpg = tl_tpg-tl_se_tpg;
+   int ret = TMR_FUNCTION_FAILED, rc;
 
tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
if (!tl_cmd) {
pr_err(Unable to allocate memory for tl_cmd\n);
-   return FAILED;
+   return ret;
}
 
tl_tmr = kzalloc(sizeof(struct tcm_loop_tmr), GFP_KERNEL);
@@ -290,6 +270,8 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
init_waitqueue_head(tl_tmr-tl_tmr_wait);
 
se_cmd = tl_cmd-tl_se_cmd;
+   se_tpg = tl_tpg-tl_se_tpg;
+   se_sess = tl_nexus-se_sess;
/*
 * Initialize struct se_cmd descriptor from target_core_mod 
infrastructure
 */
@@ -297,17 +279,20 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
DMA_NONE, MSG_SIMPLE_TAG,
tl_cmd-tl_sense_buf[0]);
 
-   rc = core_tmr_alloc_req(se_cmd, tl_tmr, TMR_LUN_RESET, GFP_KERNEL);
+   rc = core_tmr_alloc_req(se_cmd, tl_tmr, tmr, GFP_KERNEL);
if (rc  0)
goto release;
+
/*
-* Locate the underlying TCM struct se_lun from sc-device-lun
+* Locate the underlying TCM struct se_lun
 */
-   if (transport_lookup_tmr_lun(se_cmd, sc-device-lun)  0)
+   if (transport_lookup_tmr_lun(se_cmd, lun)  0) {
+   ret = TMR_LUN_DOES_NOT_EXIST;
goto release;
+   }
/*
-* Queue the TMR to TCM Core and sleep waiting for 
tcm_loop_queue_tm_rsp()
-* to wake us up.
+* Queue the TMR to TCM Core and sleep waiting for
+* tcm_loop_queue_tm_rsp() to wake us up.
 */
transport_generic_handle_tmr(se_cmd);
wait_event(tl_tmr-tl_tmr_wait, atomic_read(tl_tmr-tmr_complete));
@@ -315,8 +300,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
 * The TMR LUN_RESET has completed, check the response status and
 * then release allocations.
 */
-   ret = (se_cmd-se_tmr_req-response == TMR_FUNCTION_COMPLETE) ?
-   SUCCESS : FAILED;
+   ret = se_cmd-se_tmr_req-response;
 release:
if (se_cmd)
transport_generic_free_cmd(se_cmd, 1);
@@ -326,6 +310,39 @@ release:
return ret;
 }
 
+/*
+ * Called from SCSI EH process context to issue a LUN_RESET TMR
+ * to struct scsi_device
+ */
+static int tcm_loop_device_reset(struct scsi_cmnd *sc)
+{
+   struct tcm_loop_hba *tl_hba;
+   struct tcm_loop_nexus *tl_nexus;
+   struct tcm_loop_tpg *tl_tpg;
+   int ret = FAILED;
+
+   /*
+* Locate the tcm_loop_hba_t pointer
+*/
+   tl_hba = *(struct tcm_loop_hba **)shost_priv(sc-device-host);
+   /*
+* Locate the tl_nexus and se_sess pointers
+*/
+   tl_nexus = tl_hba-tl_nexus;
+   if (!tl_nexus) {
+   pr_err(Unable to perform device reset without
+active I_T Nexus\n);
+   return FAILED;
+   }
+   /*
+* Locate the tl_tpg pointer from TargetID in 

[PATCH 2/5] tcm_loop: Implement transport offline

2013-10-16 Thread Hannes Reinecke
Add attribute 'transport_status' to simulate link failure.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/loopback/tcm_loop.c | 53 +-
 drivers/target/loopback/tcm_loop.h |  4 +++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/target/loopback/tcm_loop.c 
b/drivers/target/loopback/tcm_loop.c
index 57d5a95..f81ebe4 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -178,7 +178,10 @@ static void tcm_loop_submission_work(struct work_struct 
*work)
set_host_byte(sc, DID_NO_CONNECT);
goto out_done;
}
-
+   if (tl_tpg-tl_transport_status == TCM_TRANSPORT_OFFLINE) {
+   set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
+   goto out_done;
+   }
tl_nexus = tl_hba-tl_nexus;
if (!tl_nexus) {
scmd_printk(KERN_ERR, sc, TCM_Loop I_T Nexus
@@ -1064,8 +1067,56 @@ check_newline:
 
 TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
 
+static ssize_t tcm_loop_tpg_show_transport_status(
+   struct se_portal_group *se_tpg,
+   char *page)
+{
+   struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
+   struct tcm_loop_tpg, tl_se_tpg);
+   const char *status = NULL;
+   ssize_t ret = -EINVAL;
+
+   switch (tl_tpg-tl_transport_status) {
+   case TCM_TRANSPORT_ONLINE:
+   status = online;
+   break;
+   case TCM_TRANSPORT_OFFLINE:
+   status = offline;
+   break;
+   default:
+   break;
+   }
+
+   if (status)
+   ret = snprintf(page, PAGE_SIZE, %s\n, status);
+
+   return ret;
+}
+
+static ssize_t tcm_loop_tpg_store_transport_status(
+   struct se_portal_group *se_tpg,
+   const char *page,
+   size_t count)
+{
+   struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
+   struct tcm_loop_tpg, tl_se_tpg);
+
+   if (!strncmp(page, online, 6)) {
+   tl_tpg-tl_transport_status = TCM_TRANSPORT_ONLINE;
+   return count;
+   }
+   if (!strncmp(page, offline, 7)) {
+   tl_tpg-tl_transport_status = TCM_TRANSPORT_OFFLINE;
+   return count;
+   }
+   return -EINVAL;
+}
+
+TF_TPG_BASE_ATTR(tcm_loop, transport_status, S_IRUGO | S_IWUSR);
+
 static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
tcm_loop_tpg_nexus.attr,
+   tcm_loop_tpg_transport_status.attr,
NULL,
 };
 
diff --git a/drivers/target/loopback/tcm_loop.h 
b/drivers/target/loopback/tcm_loop.h
index dd7a84e..56528f7 100644
--- a/drivers/target/loopback/tcm_loop.h
+++ b/drivers/target/loopback/tcm_loop.h
@@ -40,8 +40,12 @@ struct tcm_loop_nacl {
struct se_node_acl se_node_acl;
 };
 
+#define TCM_TRANSPORT_ONLINE 0
+#define TCM_TRANSPORT_OFFLINE 1
+
 struct tcm_loop_tpg {
unsigned short tl_tpgt;
+   unsigned short tl_transport_status;
atomic_t tl_tpg_port_count;
struct se_portal_group tl_se_tpg;
struct tcm_loop_hba *tl_hba;
-- 
1.7.12.4

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


[PATCH 5/5] tcm_loop: Implement target reset

2013-10-16 Thread Hannes Reinecke
Implement target reset by resetting the transport status.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/loopback/tcm_loop.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/drivers/target/loopback/tcm_loop.c 
b/drivers/target/loopback/tcm_loop.c
index febe166..d52c0aa 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -392,6 +392,32 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
 }
 
+static int tcm_loop_target_reset(struct scsi_cmnd *sc)
+{
+   struct tcm_loop_hba *tl_hba;
+   struct tcm_loop_tpg *tl_tpg;
+   int ret = FAILED;
+
+   /*
+* Locate the tcm_loop_hba_t pointer
+*/
+   tl_hba = *(struct tcm_loop_hba **)shost_priv(sc-device-host);
+   if (!tl_hba) {
+   pr_err(Unable to perform device reset without
+active I_T Nexus\n);
+   return FAILED;
+   }
+   /*
+* Locate the tl_tpg pointer from TargetID in sc-device-id
+*/
+   tl_tpg = tl_hba-tl_hba_tpgs[sc-device-id];
+   if (tl_tpg) {
+   tl_tpg-tl_transport_status = TCM_TRANSPORT_ONLINE;
+   return SUCCESS;
+   }
+   return FAILED;
+}
+
 static int tcm_loop_slave_alloc(struct scsi_device *sd)
 {
set_bit(QUEUE_FLAG_BIDI, sd-request_queue-queue_flags);
@@ -421,6 +447,7 @@ static struct scsi_host_template tcm_loop_driver_template = 
{
.change_queue_type  = tcm_loop_change_queue_type,
.eh_abort_handler = tcm_loop_abort_task,
.eh_device_reset_handler = tcm_loop_device_reset,
+   .eh_target_reset_handler = tcm_loop_target_reset,
.can_queue  = 1024,
.this_id= -1,
.sg_tablesize   = 256,
-- 
1.7.12.4

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


[PATCH 1/5] tcm_loop: Check for valid hba in tcm_loop_drop_nexus()

2013-10-16 Thread Hannes Reinecke
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/loopback/tcm_loop.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/target/loopback/tcm_loop.c 
b/drivers/target/loopback/tcm_loop.c
index 0f6d69d..57d5a95 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -932,7 +932,10 @@ static int tcm_loop_drop_nexus(
struct tcm_loop_nexus *tl_nexus;
struct tcm_loop_hba *tl_hba = tpg-tl_hba;
 
-   tl_nexus = tpg-tl_hba-tl_nexus;
+   if (!tl_hba)
+   return -ENODEV;
+
+   tl_nexus = tl_hba-tl_nexus;
if (!tl_nexus)
return -ENODEV;
 
-- 
1.7.12.4

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


[PATCH 02/11] target_core_alua: Store supported ALUA states

2013-10-16 Thread Hannes Reinecke
The supported ALUA states might be different for individual
devices, so store it in a separate field.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c | 14 --
 drivers/target/target_core_alua.h | 11 +++
 include/target/target_core_base.h |  1 +
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index 8297d37..255e83c 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -117,12 +117,7 @@ target_emulate_report_target_port_groups(struct se_cmd 
*cmd)
/*
 * Set supported ASYMMETRIC ACCESS State bits
 */
-   buf[off] = 0x80; /* T_SUP */
-   buf[off] |= 0x40; /* O_SUP */
-   buf[off] |= 0x8; /* U_SUP */
-   buf[off] |= 0x4; /* S_SUP */
-   buf[off] |= 0x2; /* AN_SUP */
-   buf[off++] |= 0x1; /* AO_SUP */
+   buf[off++] |= tg_pt_gp-tg_pt_gp_alua_supported_states;
/*
 * TARGET PORT GROUP
 */
@@ -1367,6 +1362,13 @@ struct t10_alua_tg_pt_gp 
*core_alua_allocate_tg_pt_gp(struct se_device *dev,
tg_pt_gp-tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
tg_pt_gp-tg_pt_gp_implicit_trans_secs = 
ALUA_DEFAULT_IMPLICIT_TRANS_SECS;
 
+   /*
+* Enable all supported states
+*/
+   tg_pt_gp-tg_pt_gp_alua_supported_states =
+   ALUA_T_SUP | ALUA_O_SUP | \
+   ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
+
if (def_group) {
spin_lock(dev-t10_alua.tg_pt_gps_lock);
tg_pt_gp-tg_pt_gp_id =
diff --git a/drivers/target/target_core_alua.h 
b/drivers/target/target_core_alua.h
index 74cf0c0..e826a65 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -23,6 +23,17 @@
 #define ALUA_ACCESS_STATE_TRANSITION   0xf
 
 /*
+ * from spc4r36j section 6.37 Table 306
+ */
+#define ALUA_T_SUP 0x80
+#define ALUA_O_SUP 0x40
+#define ALUA_LBD_SUP   0x10
+#define ALUA_U_SUP 0x08
+#define ALUA_S_SUP 0x04
+#define ALUA_AN_SUP0x02
+#define ALUA_AO_SUP0x01
+
+/*
  * REPORT_TARGET_PORT_GROUP STATUS CODE
  *
  * from spc4r17 section 6.27 Table 246
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index 1c6e54d..21f4bd5 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -282,6 +282,7 @@ struct t10_alua_lu_gp_member {
 struct t10_alua_tg_pt_gp {
u16 tg_pt_gp_id;
int tg_pt_gp_valid_id;
+   int tg_pt_gp_alua_supported_states;
int tg_pt_gp_alua_access_status;
int tg_pt_gp_alua_access_type;
int tg_pt_gp_nonop_delay_msecs;
-- 
1.7.12.4

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


[PATCH 07/11] target_core_alua: Allocate ALUA metadata on demand

2013-10-16 Thread Hannes Reinecke
We should only allocate ALUA metadata if we're actually going
to write them.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c | 70 +--
 drivers/target/target_core_alua.h |  3 ++
 include/target/target_core_base.h |  3 --
 3 files changed, 34 insertions(+), 42 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index a420778..b1d08bf 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -762,16 +762,22 @@ static int core_alua_write_tpg_metadata(
  */
 static int core_alua_update_tpg_primary_metadata(
struct t10_alua_tg_pt_gp *tg_pt_gp,
-   int primary_state,
-   unsigned char *md_buf)
+   int primary_state)
 {
+   unsigned char *md_buf;
struct t10_wwn *wwn = tg_pt_gp-tg_pt_gp_dev-t10_wwn;
char path[ALUA_METADATA_PATH_LEN];
-   int len;
+   int len, rc;
+
+   md_buf = kzalloc(ALUA_MD_BUF_LEN, GFP_KERNEL);
+   if (!md_buf) {
+   pr_err(Unable to allocate buf for ALUA metadata\n);
+   return -ENOMEM;
+   }
 
memset(path, 0, ALUA_METADATA_PATH_LEN);
 
-   len = snprintf(md_buf, tg_pt_gp-tg_pt_gp_md_buf_len,
+   len = snprintf(md_buf, ALUA_MD_BUF_LEN,
tg_pt_gp_id=%hu\n
alua_access_state=0x%02x\n
alua_access_status=0x%02x\n,
@@ -782,14 +788,15 @@ static int core_alua_update_tpg_primary_metadata(
/var/target/alua/tpgs_%s/%s, wwn-unit_serial[0],
config_item_name(tg_pt_gp-tg_pt_gp_group.cg_item));
 
-   return core_alua_write_tpg_metadata(path, md_buf, len);
+   rc = core_alua_write_tpg_metadata(path, md_buf, len);
+   kfree(md_buf);
+   return rc;
 }
 
 static int core_alua_do_transition_tg_pt(
struct t10_alua_tg_pt_gp *tg_pt_gp,
struct se_port *l_port,
struct se_node_acl *nacl,
-   unsigned char *md_buf,
int new_state,
int explicit)
 {
@@ -877,8 +884,7 @@ static int core_alua_do_transition_tg_pt(
 */
if (tg_pt_gp-tg_pt_gp_write_metadata) {
mutex_lock(tg_pt_gp-tg_pt_gp_md_mutex);
-   core_alua_update_tpg_primary_metadata(tg_pt_gp,
-   new_state, md_buf);
+   core_alua_update_tpg_primary_metadata(tg_pt_gp, new_state);
mutex_unlock(tg_pt_gp-tg_pt_gp_md_mutex);
}
/*
@@ -909,19 +915,12 @@ int core_alua_do_port_transition(
struct t10_alua_lu_gp *lu_gp;
struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem;
struct t10_alua_tg_pt_gp *tg_pt_gp;
-   unsigned char *md_buf;
int primary, valid_states;
 
valid_states = l_tg_pt_gp-tg_pt_gp_alua_supported_states;
if (core_alua_check_transition(new_state, valid_states, primary) != 0)
return -EINVAL;
 
-   md_buf = kzalloc(l_tg_pt_gp-tg_pt_gp_md_buf_len, GFP_KERNEL);
-   if (!md_buf) {
-   pr_err(Unable to allocate buf for ALUA metadata\n);
-   return -ENOMEM;
-   }
-
local_lu_gp_mem = l_dev-dev_alua_lu_gp_mem;
spin_lock(local_lu_gp_mem-lu_gp_mem_lock);
lu_gp = local_lu_gp_mem-lu_gp;
@@ -939,10 +938,9 @@ int core_alua_do_port_transition(
 * success.
 */
core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl,
-   md_buf, new_state, explicit);
+   new_state, explicit);
atomic_dec(lu_gp-lu_gp_ref_cnt);
smp_mb__after_atomic_dec();
-   kfree(md_buf);
return 0;
}
/*
@@ -992,7 +990,7 @@ int core_alua_do_port_transition(
 * success.
 */
core_alua_do_transition_tg_pt(tg_pt_gp, port,
-   nacl, md_buf, new_state, explicit);
+   nacl, new_state, explicit);
 
spin_lock(dev-t10_alua.tg_pt_gps_lock);
atomic_dec(tg_pt_gp-tg_pt_gp_ref_cnt);
@@ -1014,7 +1012,6 @@ int core_alua_do_port_transition(
 
atomic_dec(lu_gp-lu_gp_ref_cnt);
smp_mb__after_atomic_dec();
-   kfree(md_buf);
return 0;
 }
 
@@ -1023,13 +1020,18 @@ int core_alua_do_port_transition(
  */
 static int core_alua_update_tpg_secondary_metadata(
struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
-   struct se_port *port,
-   unsigned char *md_buf,
-   u32 md_buf_len)
+   struct se_port *port)
 {
+   unsigned char *md_buf;
struct se_portal_group *se_tpg = port-sep_tpg;
char path[ALUA_METADATA_PATH_LEN], wwn[ALUA_SECONDARY_METADATA_WWN_LEN];
-   int len;
+   int len, rc;
+
+   md_buf = kzalloc(ALUA_MD_BUF_LEN, 

[PATCH 00/11] target_core_mod: ALUA updates

2013-10-16 Thread Hannes Reinecke
Hi Nic,

here are some updates to TCM ALUA handling. Apart from some
minor fixes and spellchecks the main features are:
- Make supported states configurable:
  We should make the list of supported ALUA states configurable,
  as some setups would possibly like to support a small subset
  of ALUA states only.
- Asynchronous transitioning: I've switched 'transitioning'
  handling to use a workqueue, that should allow us to simulate
  asynchronous transitioning modes. IE TCM should now be capable
  of handling requests while in transitioning, and properly terminate
  these with the correct sense code.
- Include target device descriptor in VPD page 83
  For the ALUA device handler we'd need to identify the target device
  where a given target port belongs to. So include the respective
  values in the VPD page.

Hannes Reinecke (11):
  target core: rename (ex,im)plict - (ex,im)plicit
  target_core_alua: Store supported ALUA states
  target_core_alua: Make supported states configurable
  target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED
  target_core_alua: spellcheck
  target_core_alua: Validate ALUA state transition
  target_core_alua: Allocate ALUA metadata on demand
  target_core_alua: store old and pending ALUA state
  target_core_alua: Use workqueue for ALUA transitioning
  target_core: simplify scsi_name_len calculation
  target_core_spc: Include target device descriptor in VPD page 83

 drivers/target/target_core_alua.c  | 456 -
 drivers/target/target_core_alua.h  |  36 ++-
 drivers/target/target_core_configfs.c  |  76 +-
 drivers/target/target_core_device.c|   6 +-
 drivers/target/target_core_file.c  |   2 +-
 drivers/target/target_core_pr.c|  24 +-
 drivers/target/target_core_spc.c   |  62 -
 drivers/target/target_core_transport.c |   4 +-
 drivers/target/target_core_ua.h|   2 +-
 include/target/target_core_base.h  |  14 +-
 10 files changed, 442 insertions(+), 240 deletions(-)

-- 
1.7.12.4

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


[PATCH 03/11] target_core_alua: Make supported states configurable

2013-10-16 Thread Hannes Reinecke
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_configfs.c | 50 +++
 1 file changed, 50 insertions(+)

diff --git a/drivers/target/target_core_configfs.c 
b/drivers/target/target_core_configfs.c
index d4c28a3..53e9e00 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2131,6 +2131,55 @@ static ssize_t 
target_core_alua_tg_pt_gp_store_attr_alua_access_type(
 SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
 
 /*
+ * alua_supported_states
+ */
+static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_supported_states(
+   struct t10_alua_tg_pt_gp *tg_pt_gp,
+   char *page)
+{
+   return sprintf(page, %02x\n,
+   tg_pt_gp-tg_pt_gp_alua_supported_states);
+}
+
+static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_supported_states(
+   struct t10_alua_tg_pt_gp *tg_pt_gp,
+   const char *page,
+   size_t count)
+{
+   unsigned long tmp;
+   int new_states, valid_states, ret;
+
+   if (!tg_pt_gp-tg_pt_gp_valid_id) {
+   pr_err(Unable to do set supported ALUA states on non
+valid tg_pt_gp ID: %hu\n,
+   tg_pt_gp-tg_pt_gp_valid_id);
+   return -EINVAL;
+   }
+
+   ret = strict_strtoul(page, 0, tmp);
+   if (ret  0) {
+   pr_err(Unable to extract new supported ALUA states
+from %s\n, page);
+   return -EINVAL;
+   }
+   new_states = (int)tmp;
+   valid_states = ALUA_T_SUP | ALUA_O_SUP | ALUA_LBD_SUP | \
+   ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
+
+
+   if (new_states  ~valid_states) {
+   pr_err(Illegal supported ALUA states: 0x%02x\n,
+   new_states);
+   return -EINVAL;
+   }
+
+   tg_pt_gp-tg_pt_gp_alua_supported_states = new_states;
+   return count;
+}
+
+SE_DEV_ALUA_TG_PT_ATTR(alua_supported_states, S_IRUGO | S_IWUSR);
+
+/*
  * alua_write_metadata
  */
 static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_write_metadata(
@@ -2350,6 +2399,7 @@ static struct configfs_attribute 
*target_core_alua_tg_pt_gp_attrs[] = {
target_core_alua_tg_pt_gp_alua_access_state.attr,
target_core_alua_tg_pt_gp_alua_access_status.attr,
target_core_alua_tg_pt_gp_alua_access_type.attr,
+   target_core_alua_tg_pt_gp_alua_supported_states.attr,
target_core_alua_tg_pt_gp_alua_write_metadata.attr,
target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
-- 
1.7.12.4

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


[PATCH 09/11] target_core_alua: Use workqueue for ALUA transitioning

2013-10-16 Thread Hannes Reinecke
Use a workqueue for processing ALUA state transitions; this allows
us to process implicit delay properly.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c | 174 +++---
 include/target/target_core_base.h |   4 +
 2 files changed, 128 insertions(+), 50 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index 33e3f23..166bee6 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -761,8 +761,7 @@ static int core_alua_write_tpg_metadata(
  * Called with tg_pt_gp-tg_pt_gp_md_mutex held
  */
 static int core_alua_update_tpg_primary_metadata(
-   struct t10_alua_tg_pt_gp *tg_pt_gp,
-   int primary_state)
+   struct t10_alua_tg_pt_gp *tg_pt_gp)
 {
unsigned char *md_buf;
struct t10_wwn *wwn = tg_pt_gp-tg_pt_gp_dev-t10_wwn;
@@ -781,7 +780,8 @@ static int core_alua_update_tpg_primary_metadata(
tg_pt_gp_id=%hu\n
alua_access_state=0x%02x\n
alua_access_status=0x%02x\n,
-   tg_pt_gp-tg_pt_gp_id, primary_state,
+   tg_pt_gp-tg_pt_gp_id,
+   tg_pt_gp-tg_pt_gp_alua_pending_state,
tg_pt_gp-tg_pt_gp_alua_access_status);
 
snprintf(path, ALUA_METADATA_PATH_LEN,
@@ -793,36 +793,17 @@ static int core_alua_update_tpg_primary_metadata(
return rc;
 }
 
-static int core_alua_do_transition_tg_pt(
-   struct t10_alua_tg_pt_gp *tg_pt_gp,
-   struct se_port *l_port,
-   struct se_node_acl *nacl,
-   int new_state,
-   int explicit)
+static void core_alua_do_transition_tg_pt_work(struct work_struct *work)
 {
+   struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(work,
+   struct t10_alua_tg_pt_gp, tg_pt_gp_transition_work.work);
+   struct se_device *dev = tg_pt_gp-tg_pt_gp_dev;
struct se_dev_entry *se_deve;
struct se_lun_acl *lacl;
struct se_port *port;
struct t10_alua_tg_pt_gp_member *mem;
-
-   /*
-* Save the old primary ALUA access state, and set the current state
-* to ALUA_ACCESS_STATE_TRANSITION.
-*/
-   tg_pt_gp-tg_pt_gp_alua_previous_state =
-   atomic_read(tg_pt_gp-tg_pt_gp_alua_access_state);
-   tg_pt_gp-tg_pt_gp_alua_pending_state = new_state;
-
-   atomic_set(tg_pt_gp-tg_pt_gp_alua_access_state,
-   ALUA_ACCESS_STATE_TRANSITION);
-   tg_pt_gp-tg_pt_gp_alua_access_status = (explicit) ?
-   ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
-   ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
-   /*
-* Check for the optional ALUA primary state transition delay
-*/
-   if (tg_pt_gp-tg_pt_gp_trans_delay_msecs != 0)
-   msleep_interruptible(tg_pt_gp-tg_pt_gp_trans_delay_msecs);
+   bool explicit = (tg_pt_gp-tg_pt_gp_alua_access_status ==
+ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG);
 
spin_lock(tg_pt_gp-tg_pt_gp_lock);
list_for_each_entry(mem, tg_pt_gp-tg_pt_gp_mem_list,
@@ -857,9 +838,12 @@ static int core_alua_do_transition_tg_pt(
if (!lacl)
continue;
 
-   if (explicit 
-  (nacl != NULL)  (nacl == lacl-se_lun_nacl) 
-  (l_port != NULL)  (l_port == port))
+   if ((tg_pt_gp-tg_pt_gp_alua_access_status ==
+ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG) 
+  (tg_pt_gp-tg_pt_gp_alua_nacl != NULL) 
+   (tg_pt_gp-tg_pt_gp_alua_nacl == lacl-se_lun_nacl) 

+  (tg_pt_gp-tg_pt_gp_alua_port != NULL) 
+   (tg_pt_gp-tg_pt_gp_alua_port == port))
continue;
 
core_scsi3_ua_allocate(lacl-se_lun_nacl,
@@ -887,7 +871,7 @@ static int core_alua_do_transition_tg_pt(
 */
if (tg_pt_gp-tg_pt_gp_write_metadata) {
mutex_lock(tg_pt_gp-tg_pt_gp_md_mutex);
-   core_alua_update_tpg_primary_metadata(tg_pt_gp, new_state);
+   core_alua_update_tpg_primary_metadata(tg_pt_gp);
mutex_unlock(tg_pt_gp-tg_pt_gp_md_mutex);
}
/*
@@ -902,6 +886,87 @@ static int core_alua_do_transition_tg_pt(
tg_pt_gp-tg_pt_gp_id,
core_alua_dump_state(tg_pt_gp-tg_pt_gp_alua_previous_state),
core_alua_dump_state(tg_pt_gp-tg_pt_gp_alua_pending_state));
+   spin_lock(dev-t10_alua.tg_pt_gps_lock);
+   atomic_dec(tg_pt_gp-tg_pt_gp_ref_cnt);
+   smp_mb__after_atomic_dec();
+   spin_unlock(dev-t10_alua.tg_pt_gps_lock);
+
+   if (tg_pt_gp-tg_pt_gp_transition_complete)
+   complete(tg_pt_gp-tg_pt_gp_transition_complete);
+}
+

[PATCH 04/11] target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED

2013-10-16 Thread Hannes Reinecke
Rename ALUA_ACCESS_STATE_OPTMIZED to
ALUA_ACCESS_STATE_OPTIMIZED.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c | 10 +-
 drivers/target/target_core_alua.h |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index 255e83c..593de80 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -561,12 +561,12 @@ target_alua_state_check(struct se_cmd *cmd)
nonop_delay_msecs = tg_pt_gp-tg_pt_gp_nonop_delay_msecs;
spin_unlock(tg_pt_gp_mem-tg_pt_gp_mem_lock);
/*
-* Process ALUA_ACCESS_STATE_ACTIVE_OPTMIZED in a separate conditional
+* Process ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED in a separate conditional
 * statement so the compiler knows explicitly to check this case first.
 * For the Optimized ALUA access state case, we want to process the
 * incoming fabric cmd ASAP..
 */
-   if (out_alua_state == ALUA_ACCESS_STATE_ACTIVE_OPTMIZED)
+   if (out_alua_state == ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED)
return 0;
 
switch (out_alua_state) {
@@ -621,7 +621,7 @@ static sense_reason_t
 core_alua_check_transition(int state, int *primary)
 {
switch (state) {
-   case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED:
+   case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
case ALUA_ACCESS_STATE_STANDBY:
case ALUA_ACCESS_STATE_UNAVAILABLE:
@@ -649,7 +649,7 @@ core_alua_check_transition(int state, int *primary)
 static char *core_alua_dump_state(int state)
 {
switch (state) {
-   case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED:
+   case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
return Active/Optimized;
case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
return Active/NonOptimized;
@@ -1349,7 +1349,7 @@ struct t10_alua_tg_pt_gp 
*core_alua_allocate_tg_pt_gp(struct se_device *dev,
tg_pt_gp-tg_pt_gp_dev = dev;
tg_pt_gp-tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN;
atomic_set(tg_pt_gp-tg_pt_gp_alua_access_state,
-   ALUA_ACCESS_STATE_ACTIVE_OPTMIZED);
+   ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED);
/*
 * Enable both explicit and implicit ALUA support by default
 */
diff --git a/drivers/target/target_core_alua.h 
b/drivers/target/target_core_alua.h
index e826a65..88e2e83 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -15,7 +15,7 @@
  *
  * from spc4r17 section 6.27 Table 245
  */
-#define ALUA_ACCESS_STATE_ACTIVE_OPTMIZED  0x0
+#define ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED 0x0
 #define ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED 0x1
 #define ALUA_ACCESS_STATE_STANDBY  0x2
 #define ALUA_ACCESS_STATE_UNAVAILABLE  0x3
-- 
1.7.12.4

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


[PATCH 06/11] target_core_alua: Validate ALUA state transition

2013-10-16 Thread Hannes Reinecke
As we now can modify the list of supported states we need to
validate the requested ALUA state when doing a state transition.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c | 85 ++-
 1 file changed, 56 insertions(+), 29 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index a16115e..a420778 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -41,7 +41,8 @@
 #include target_core_alua.h
 #include target_core_ua.h
 
-static sense_reason_t core_alua_check_transition(int state, int *primary);
+static sense_reason_t core_alua_check_transition(int state, int valid,
+int *primary);
 static int core_alua_set_tg_pt_secondary_state(
struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
struct se_port *port, int explicit, int offline);
@@ -210,7 +211,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
unsigned char *ptr;
sense_reason_t rc = TCM_NO_SENSE;
u32 len = 4; /* Skip over RESERVED area in header */
-   int alua_access_state, primary = 0;
+   int alua_access_state, primary = 0, valid_states;
u16 tg_pt_id, rtpi;
 
if (!l_port)
@@ -252,6 +253,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
rc = TCM_UNSUPPORTED_SCSI_OPCODE;
goto out;
}
+   valid_states = l_tg_pt_gp-tg_pt_gp_alua_supported_states;
 
ptr = buf[4]; /* Skip over RESERVED area in header */
 
@@ -263,7 +265,8 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
 * the state is a primary or secondary target port asymmetric
 * access state.
 */
-   rc = core_alua_check_transition(alua_access_state, primary);
+   rc = core_alua_check_transition(alua_access_state,
+   valid_states, primary);
if (rc) {
/*
 * If the SET TARGET PORT GROUPS attempts to establish
@@ -614,21 +617,57 @@ out:
return 0;
 }
 
+static char *core_alua_dump_state(int state)
+{
+   switch (state) {
+   case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
+   return Active/Optimized;
+   case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
+   return Active/NonOptimized;
+   case ALUA_ACCESS_STATE_STANDBY:
+   return Standby;
+   case ALUA_ACCESS_STATE_UNAVAILABLE:
+   return Unavailable;
+   case ALUA_ACCESS_STATE_OFFLINE:
+   return Offline;
+   case ALUA_ACCESS_STATE_TRANSITION:
+   return Transitioning;
+   default:
+   return Unknown;
+   }
+
+   return NULL;
+}
+
 /*
  * Check implicit and explicit ALUA state change request.
  */
 static sense_reason_t
-core_alua_check_transition(int state, int *primary)
+core_alua_check_transition(int state, int valid, int *primary)
 {
+   /*
+* OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are
+* defined as primary target port asymmetric access states.
+*/
switch (state) {
case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
+   if (!(valid  ALUA_AO_SUP))
+   goto not_supported;
+   *primary = 1;
+   break;
case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
+   if (!(valid  ALUA_AN_SUP))
+   goto not_supported;
+   *primary = 1;
+   break;
case ALUA_ACCESS_STATE_STANDBY:
+   if (!(valid  ALUA_S_SUP))
+   goto not_supported;
+   *primary = 1;
+   break;
case ALUA_ACCESS_STATE_UNAVAILABLE:
-   /*
-* OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are
-* defined as primary target port asymmetric access states.
-*/
+   if (!(valid  ALUA_U_SUP))
+   goto not_supported;
*primary = 1;
break;
case ALUA_ACCESS_STATE_OFFLINE:
@@ -636,6 +675,8 @@ core_alua_check_transition(int state, int *primary)
 * OFFLINE state is defined as a secondary target port
 * asymmetric access state.
 */
+   if (!(valid  ALUA_O_SUP))
+   goto not_supported;
*primary = 0;
break;
default:
@@ -644,26 +685,11 @@ core_alua_check_transition(int state, int *primary)
}
 
return 0;
-}
 
-static char *core_alua_dump_state(int state)
-{
-   switch (state) {
-   case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
-   return Active/Optimized;
-   case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
-   return Active/NonOptimized;
-   case 

[PATCH 08/11] target_core_alua: store old and pending ALUA state

2013-10-16 Thread Hannes Reinecke
During state transition we should be storing both the original
and the pending state.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c | 15 ++-
 include/target/target_core_base.h |  6 --
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index b1d08bf..33e3f23 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -804,12 +804,15 @@ static int core_alua_do_transition_tg_pt(
struct se_lun_acl *lacl;
struct se_port *port;
struct t10_alua_tg_pt_gp_member *mem;
-   int old_state = 0;
+
/*
 * Save the old primary ALUA access state, and set the current state
 * to ALUA_ACCESS_STATE_TRANSITION.
 */
-   old_state = atomic_read(tg_pt_gp-tg_pt_gp_alua_access_state);
+   tg_pt_gp-tg_pt_gp_alua_previous_state =
+   atomic_read(tg_pt_gp-tg_pt_gp_alua_access_state);
+   tg_pt_gp-tg_pt_gp_alua_pending_state = new_state;
+
atomic_set(tg_pt_gp-tg_pt_gp_alua_access_state,
ALUA_ACCESS_STATE_TRANSITION);
tg_pt_gp-tg_pt_gp_alua_access_status = (explicit) ?
@@ -890,13 +893,15 @@ static int core_alua_do_transition_tg_pt(
/*
 * Set the current primary ALUA access state to the requested new state
 */
-   atomic_set(tg_pt_gp-tg_pt_gp_alua_access_state, new_state);
+   atomic_set(tg_pt_gp-tg_pt_gp_alua_access_state,
+  tg_pt_gp-tg_pt_gp_alua_pending_state);
 
pr_debug(Successful %s ALUA transition TG PT Group: %s ID: %hu
 from primary access state %s to %s\n, (explicit) ? 
explicit :
implicit, config_item_name(tg_pt_gp-tg_pt_gp_group.cg_item),
-   tg_pt_gp-tg_pt_gp_id, core_alua_dump_state(old_state),
-   core_alua_dump_state(new_state));
+   tg_pt_gp-tg_pt_gp_id,
+   core_alua_dump_state(tg_pt_gp-tg_pt_gp_alua_previous_state),
+   core_alua_dump_state(tg_pt_gp-tg_pt_gp_alua_pending_state));
 
return 0;
 }
diff --git a/include/target/target_core_base.h 
b/include/target/target_core_base.h
index 933c59d..67b6ca2 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -282,8 +282,10 @@ struct t10_alua_lu_gp_member {
 struct t10_alua_tg_pt_gp {
u16 tg_pt_gp_id;
int tg_pt_gp_valid_id;
-   int tg_pt_gp_alua_supported_states;
-   int tg_pt_gp_alua_access_status;
+   u8  tg_pt_gp_alua_pending_state;
+   u8  tg_pt_gp_alua_previous_state;
+   u8  tg_pt_gp_alua_supported_states;
+   u8  tg_pt_gp_alua_access_status;
int tg_pt_gp_alua_access_type;
int tg_pt_gp_nonop_delay_msecs;
int tg_pt_gp_trans_delay_msecs;
-- 
1.7.12.4

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


[PATCH 2/2] target_core_alua: Referrals configfs integration

2013-10-16 Thread Hannes Reinecke
Referrals need an LBA map, which needs to be kept
consistent across all target port groups. So
instead of tying the map to the target port groups
I've implemented a single attribute containing the
entire map.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c  | 101 +++
 drivers/target/target_core_alua.h  |   8 ++
 drivers/target/target_core_configfs.c  | 171 +
 drivers/target/target_core_device.c|   1 +
 drivers/target/target_core_transport.c |  28 +-
 5 files changed, 308 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index 8f66146..9dd01ff 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -1340,6 +1340,107 @@ static int core_alua_set_tg_pt_secondary_state(
return 0;
 }
 
+struct t10_alua_lba_map *
+core_alua_allocate_lba_map(struct list_head *list,
+  u64 first_lba, u64 last_lba)
+{
+   struct t10_alua_lba_map *lba_map;
+
+   lba_map = kmem_cache_zalloc(t10_alua_lba_map_cache, GFP_KERNEL);
+   if (!lba_map) {
+   pr_err(Unable to allocate struct t10_alua_lba_map\n);
+   return ERR_PTR(-ENOMEM);
+   }
+   INIT_LIST_HEAD(lba_map-lba_map_mem_list);
+   lba_map-lba_map_first_lba = first_lba;
+   lba_map-lba_map_last_lba = last_lba;
+
+   list_add_tail(lba_map-lba_map_list, list);
+   return lba_map;
+}
+
+int
+core_alua_allocate_lba_map_mem(struct t10_alua_lba_map *lba_map,
+  int pg_id, int state)
+{
+   struct t10_alua_lba_map_member *lba_map_mem;
+
+   list_for_each_entry(lba_map_mem, lba_map-lba_map_mem_list,
+   lba_map_mem_list) {
+   if (lba_map_mem-lba_map_mem_alua_pg_id == pg_id) {
+   pr_err(Duplicate pg_id %d in lba_map\n, pg_id);
+   return -EINVAL;
+   }
+   }
+
+   lba_map_mem = kmem_cache_zalloc(t10_alua_lba_map_mem_cache, GFP_KERNEL);
+   if (!lba_map_mem) {
+   pr_err(Unable to allocate struct t10_alua_lba_map_mem\n);
+   return -ENOMEM;
+   }
+   lba_map_mem-lba_map_mem_alua_state = state;
+   lba_map_mem-lba_map_mem_alua_pg_id = pg_id;
+
+   list_add_tail(lba_map_mem-lba_map_mem_list,
+ lba_map-lba_map_mem_list);
+   return 0;
+}
+
+void
+core_alua_free_lba_map(struct list_head *lba_list)
+{
+   struct t10_alua_lba_map *lba_map, *lba_map_tmp;
+   struct t10_alua_lba_map_member *lba_map_mem, *lba_map_mem_tmp;
+
+   list_for_each_entry_safe(lba_map, lba_map_tmp, lba_list,
+lba_map_list) {
+   list_for_each_entry_safe(lba_map_mem, lba_map_mem_tmp,
+lba_map-lba_map_mem_list,
+lba_map_mem_list) {
+   list_del(lba_map_mem-lba_map_mem_list);
+   kmem_cache_free(t10_alua_lba_map_mem_cache,
+   lba_map_mem);
+   }
+   list_del(lba_map-lba_map_list);
+   kmem_cache_free(t10_alua_lba_map_cache, lba_map);
+   }
+}
+
+void
+core_alua_set_lba_map(struct se_device *dev, struct list_head *lba_map_list,
+ int segment_size, int segment_mult)
+{
+   struct list_head old_lba_map_list;
+   struct t10_alua_tg_pt_gp *tg_pt_gp;
+   int activate = 0, supported;
+
+   INIT_LIST_HEAD(old_lba_map_list);
+   spin_lock(dev-t10_alua.lba_map_lock);
+   dev-t10_alua.lba_map_segment_size = segment_size;
+   dev-t10_alua.lba_map_segment_multiplier = segment_mult;
+   list_splice_init(dev-t10_alua.lba_map_list, old_lba_map_list);
+   if (lba_map_list) {
+   list_splice_init(lba_map_list, dev-t10_alua.lba_map_list);
+   activate = 1;
+   }
+   spin_unlock(dev-t10_alua.lba_map_lock);
+   spin_lock(dev-t10_alua.tg_pt_gps_lock);
+   list_for_each_entry(tg_pt_gp, dev-t10_alua.tg_pt_gps_list,
+   tg_pt_gp_list) {
+
+   if (!tg_pt_gp-tg_pt_gp_valid_id)
+   continue;
+   supported = tg_pt_gp-tg_pt_gp_alua_supported_states;
+   if (activate)
+   supported |= ALUA_LBD_SUP;
+   else
+   supported = ~ALUA_LBD_SUP;
+   tg_pt_gp-tg_pt_gp_alua_supported_states = supported;
+   }
+   spin_unlock(dev-t10_alua.tg_pt_gps_lock);
+   core_alua_free_lba_map(old_lba_map_list);
+}
+
 struct t10_alua_lu_gp *
 core_alua_allocate_lu_gp(const char *name, int def_group)
 {
diff --git a/drivers/target/target_core_alua.h 
b/drivers/target/target_core_alua.h
index 47950cd..0a7d65e 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ 

[PATCH 1/2] target_core_alua: Referrals infrastructure

2013-10-16 Thread Hannes Reinecke
Add infrastructure for referrals.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/target/target_core_alua.c | 151 ++
 drivers/target/target_core_alua.h |   4 +-
 drivers/target/target_core_configfs.c |  12 ++-
 drivers/target/target_core_device.c   |   2 +
 drivers/target/target_core_sbc.c  |   5 +-
 drivers/target/target_core_spc.c  |  20 +
 include/scsi/scsi.h   |   1 +
 include/target/target_core_base.h |  18 
 8 files changed, 209 insertions(+), 4 deletions(-)

diff --git a/drivers/target/target_core_alua.c 
b/drivers/target/target_core_alua.c
index 166bee6..8f66146 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -56,6 +56,75 @@ static LIST_HEAD(lu_gps_list);
 struct t10_alua_lu_gp *default_lu_gp;
 
 /*
+ * REPORT REFERRALS
+ *
+ * See sbc3r35 section 5.23
+ */
+sense_reason_t
+target_emulate_report_referrals(struct se_cmd *cmd)
+{
+   struct se_device *dev = cmd-se_dev;
+   struct t10_alua_lba_map *map;
+   struct t10_alua_lba_map_member *map_mem;
+   unsigned char *buf;
+   u32 rd_len = 0, off;
+
+   if (cmd-data_length  4) {
+   pr_warn(REPORT REFERRALS allocation length %u too
+small\n, cmd-data_length);
+   return TCM_INVALID_CDB_FIELD;
+   }
+
+   buf = transport_kmap_data_sg(cmd);
+   if (!buf)
+   return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+   off = 4;
+   spin_lock(dev-t10_alua.lba_map_lock);
+   if (list_empty(dev-t10_alua.lba_map_list)) {
+   spin_unlock(dev-t10_alua.lba_map_lock);
+   transport_kunmap_data_sg(cmd);
+
+   return TCM_UNSUPPORTED_SCSI_OPCODE;
+   }
+
+   list_for_each_entry(map, dev-t10_alua.lba_map_list,
+   lba_map_list) {
+   int desc_num = off + 3;
+   int pg_num;
+
+   off += 4;
+   put_unaligned_be64(map-lba_map_first_lba, buf[off]);
+   off += 8;
+   put_unaligned_be64(map-lba_map_last_lba, buf[off]);
+   off += 8;
+   rd_len += 20;
+   pg_num = 0;
+   list_for_each_entry(map_mem, map-lba_map_mem_list,
+   lba_map_mem_list) {
+   buf[off++] = map_mem-lba_map_mem_alua_state  0x0f;
+   off++;
+   buf[off++] = (map_mem-lba_map_mem_alua_pg_id  8)  
0xff;
+   buf[off++] = (map_mem-lba_map_mem_alua_pg_id  0xff);
+   rd_len += 4;
+   pg_num++;
+   }
+   buf[desc_num] = pg_num;
+   }
+   spin_unlock(dev-t10_alua.lba_map_lock);
+
+   /*
+* Set the RETURN DATA LENGTH set in the header of the DataIN Payload
+*/
+   put_unaligned_be16(rd_len, buf[2]);
+
+   transport_kunmap_data_sg(cmd);
+
+   target_complete_cmd(cmd, GOOD);
+   return 0;
+}
+
+/*
  * REPORT_TARGET_PORT_GROUPS
  *
  * See spc4r17 section 6.27
@@ -389,6 +458,80 @@ static inline int core_alua_state_nonoptimized(
return 0;
 }
 
+static inline int core_alua_state_lba_dependent(
+   struct se_cmd *cmd,
+   struct t10_alua_tg_pt_gp *tg_pt_gp,
+   u8 *alua_ascq)
+{
+   struct se_device *dev = cmd-se_dev;
+   u32 segment_size, segment_mult, sectors;
+   u64 lba;
+
+   /* Only need to check for cdb actually containing LBAs */
+   if (!cmd-se_cmd_flags  SCF_SCSI_DATA_CDB)
+   return 0;
+
+   spin_lock(dev-t10_alua.lba_map_lock);
+   segment_size = dev-t10_alua.lba_map_segment_size;
+   segment_mult = dev-t10_alua.lba_map_segment_multiplier;
+   sectors = cmd-data_length / dev-dev_attrib.block_size;
+
+   lba = cmd-t_task_lba;
+   while (lba  cmd-t_task_lba + sectors) {
+   struct t10_alua_lba_map *cur_map = NULL, *map;
+   struct t10_alua_lba_map_member *map_mem;
+
+   list_for_each_entry(map, dev-t10_alua.lba_map_list,
+   lba_map_list) {
+   u64 start_lba, last_lba;
+   u64 first_lba = map-lba_map_first_lba;
+
+   if (segment_mult) {
+   start_lba = lba % (segment_size * segment_mult);
+   last_lba = first_lba + segment_size - 1;
+   if (start_lba = first_lba 
+   start_lba = last_lba) {
+   lba += segment_size;
+   cur_map = map;
+   break;
+   }
+   } else {
+   last_lba = map-lba_map_last_lba;
+   if (lba = first_lba  lba = last_lba) {
+

[Bug 63141] New: Linux Kernel will shows Got wrong page in kernel log when Linux kernel tries to send SCSI ModeSense command with Page code 0x08 (Caching Mode Page)

2013-10-16 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=63141

Bug ID: 63141
   Summary: Linux Kernel will shows Got wrong page in kernel log
when Linux kernel tries to send SCSI ModeSense command
with Page code 0x08 (Caching Mode Page)
   Product: IO/Storage
   Version: 2.5
Kernel Version: 3.6.11
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: low
  Priority: P1
 Component: SCSI
  Assignee: linux-scsi@vger.kernel.org
  Reporter: leoche...@gmail.com
Regression: No

Created attachment 111291
  -- https://bugzilla.kernel.org/attachment.cgi?id=111291action=edit
SourceCodeComparsionBetween2.6.xAnd3.9.1

Reporter: Leo Chen (Li-Chung Chen)
Report Date: 10/16/13

Issue Descrition: In Linux kernel 3.6.11, sd.c file, host calls
sd_read_cache_type() function to read physical disk or volume cache type. This
function works properly on most physical disks but will fail to read the cache
type on LSI raid volume. The error message in Linux Kernel is Got wrong page.

However, the Linux kernel works properly in kernel 2.6.x.

Suggestion: If we restore below codes from 2.6.x to 3.6.11 in
sd.c,sd_read_cache_type()function, then the kernel won't report got wrong
page in the log. 

/* Take headers and block descriptors into account */
len += data.header_length + data.block_descriptor_length;

I also referenced the SPC-4(SCSI Primary Commands - 4) specification from T10
to check if it's LSI firmware problem to response the wrong parameter length to
the host. According to the description in SPC below, it looks like LSI logical
volume doesn't voilate the specification to response the MODE DATA LENGTH value
to host.

[SPC-4 Description about the Mode Parameter]
When using the MODE SENSE command, the MODE DATA LENGTH field indicates the
length in bytes of the following
data that is available to be transferred. The mode data length does not include
the number of bytes in the MODE
DATA LENGTH field. 
[SPC-4 Description about the Mode Parameter]

Therefore, I'd like to suggest the Linux Kernel to add the code above to make
the kernel handle the cache reading properly.

-- 
You are receiving this mail because:
You are the assignee for the bug.
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH][SCSI] megaraid_sas: Fix synchronization problem between sysPD IO path and AEN path

2013-10-16 Thread Sumit.Saxena
There is syncronization problem between sysPD IO path and AEN path. Driver 
maintains instance-pd_list[] array, which will get updated(by calling function 
megasas_get_pd_list[]), whenever any of below events occurs-

MR_EVT_PD_INSERTED
MR_EVT_PD_REMOVED
MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED
MR_EVT_FOREIGN_CFG_IMPORTED

At same time running sysPD IO will be accessing the same array 
instance-pd_list[], which is getting updated in AEN path, because
of this IO may not get correct PD info from instance-pd_list[] array.

Signed-off-by: Adam Radford adam.radf...@lsi.com
Signed-off-by: Sumit Saxena sumit.sax...@lsi.com
---
diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 0c73ba4..e9e543c 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1531,6 +1531,7 @@ struct megasas_instance {
struct megasas_register_set __iomem *reg_set;
u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
struct megasas_pd_list  pd_list[MEGASAS_MAX_PD];
+   struct megasas_pd_list  local_pd_list[MEGASAS_MAX_PD];
u8 ld_ids[MEGASAS_MAX_LD_IDS];
s8 init_id;
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index e62ff02..83ebc75 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3194,21 +3194,23 @@ megasas_get_pd_list(struct megasas_instance *instance)
 (le32_to_cpu(ci-count) 
  (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
 
-   memset(instance-pd_list, 0,
+   memset(instance-local_pd_list, 0,
MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
 
for (pd_index = 0; pd_index  le32_to_cpu(ci-count); 
pd_index++) {
 
-   instance-pd_list[le16_to_cpu(pd_addr-deviceId)].tid   
=
+   
instance-local_pd_list[le16_to_cpu(pd_addr-deviceId)].tid =
le16_to_cpu(pd_addr-deviceId);
-   
instance-pd_list[le16_to_cpu(pd_addr-deviceId)].driveType =
+   
instance-local_pd_list[le16_to_cpu(pd_addr-deviceId)].driveType   =
pd_addr-scsiDevType;
-   
instance-pd_list[le16_to_cpu(pd_addr-deviceId)].driveState=
+   
instance-local_pd_list[le16_to_cpu(pd_addr-deviceId)].driveState  =
MR_PD_STATE_SYSTEM;
pd_addr++;
}
}
 
+   memcpy(instance-pd_list, instance-local_pd_list,
+   sizeof(instance-pd_list));
pci_free_consistent(instance-pdev,
MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
ci, ci_h);

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


[PATCH] drivers: scsi: Remove useless casting in hpsa.c

2013-10-16 Thread Geyslan G. Bem
Casting (void *) value returned by kmalloc is useless
as mentioned in Documentation/CodingStyle, Chap 14.

Signed-off-by: Geyslan G. Bem geys...@gmail.com
---
 drivers/scsi/hpsa.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 891c86b..896a57d 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3093,8 +3093,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, 
void __user *argp)
return -EINVAL;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
-   ioc = (BIG_IOCTL_Command_struct *)
-   kmalloc(sizeof(*ioc), GFP_KERNEL);
+   ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
if (!ioc) {
status = -ENOMEM;
goto cleanup1;
-- 
1.8.4

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


Re: eSATA Drive Detection issues on mvsas

2013-10-16 Thread Praveen Murali


On 10/15/2013 06:11 PM, Dan Williams wrote:

On Tue, Oct 15, 2013 at 5:15 PM, Praveen Murali pmur...@logicube.com wrote:

Dan/James,
  Can you please take a look at this and let me know if I am at the right
place? Or point me in the right direction? As I understand, this deost not
look like an mvsas driver issue.


Looks like a latent bug in libsas to me.  Commit 110dd8f1 [SCSI]
libsas: fix scr_read/write users and update the libata documentation
looks like a compile fix when the build was broken by commit  9977126c
libata: add @is_cmd to ata_tf_to_fis() where libata changed the
interface for ata_tf_to_fis().  We were passing 0 for pmp prior to
that and changed to 1 here, probably a typo intending 'is_cmd to
always be 1.

Somehow we have gotten away with is_cmd being 0?  Does the following
patch work for you:

diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 161c98efade9..d0fb99d5da95 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -211,7 +211,7 @@ static unsigned int sas_ata_qc_issue(struct
ata_queued_cmd *qc)
 qc-tf.nsect = 0;
 }

-   ata_tf_to_fis(qc-tf, 1, 0, (u8*)task-ata_task.fis);
+   ata_tf_to_fis(qc-tf, qc-dev-link-pmp, 1, (u8*)task-ata_task.fis);
 task-uldd_task = qc;
 if (ata_is_atapi(qc-tf.protocol)) {
 memcpy(task-ata_task.atapi_packet, qc-cdb, qc-dev-cdb_len);


Hi Dan,
  I tested this patch and it works great!

Thanks,
Praveen

That being said I don't think anybody has really checked out
port-multiplier support on libsas, but we shouldn't be setting this
bit by default.

--
Dan



On 10/14/2013 05:18 PM, Praveen Murali wrote:

Hi,
   I have couple of external drives (Western Digital and Seagate) that have
an eSATA interface. My Linux box with a Marvell HBA (9445) running Ubuntu
12.04 with 3.2.48 kernel doest not seem to detect the drive. I tried with
the latest upstream kernel and it behaves the same. But both the drives
detect fine if I enter the mvsas BIOS during bootup. So I have hooked up a
SATA analyzer and this is what I found
- When I tried to detect the drives in the mvsas BIOS, all the ATA
commands that the bios issues have the port multiplier byte set to 0.
- If I bootup my Linux system and then connect the drives, the first
IDENTIFY command has the port multiplier set to 0 (this one is successful)
and the subsequent IDENTIFY command has port multiplier set to 1 (this one
fails).

I assume the first IDENTIFY is coming from the BIOS, not Linux correct?


- If I connect any other SATA drives I have to the HBA, all the ATA
commands have port multiplier set to 1 but they detects and work fine.

Just to rule out the port-multiplier possibility I changed the following
line in drivers/scsi/libsas/sas_ata.c - fucntion sas_ata_qc_issue()

ata_tf_to_fis(qc-tf, 1, 0, (u8*)task-ata_task.fis);

to

ata_tf_to_fis(qc-tf, 0, 0, (u8*)task-ata_task.fis);

now all my drives seem to detect just fine. I believe, the eSATA interface
on these external drives is a port multiplier, which is why the command
fails. Also, the normal drives ignore this field thats why they work fine
with port multiplier being set to either 0 or 1.

Question(s): Are my above assumtions correct? If so, what is the reasoning
behind setting the port multiplier to 1 by default in libsas layer?

Thanks,
Praveen




--
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: [PATCH] drivers: scsi: lpfc: Fix typo on NULL assignment

2013-10-16 Thread James Smart

Acked-by: James Smart james.sm...@emulex.com

-- james s


On 10/15/2013 8:29 PM, Felipe Pena wrote:

In the lpfc_ct_free_iocb function after freeing associated memory to the
ctiocb-context3, the ctiocb-context1 is set to NULL instead of context3.

Signed-off-by: Felipe Pena felipe...@gmail.com
---
  drivers/scsi/lpfc/lpfc_ct.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 02e8cd9..da61d8d 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -280,7 +280,7 @@ lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq 
*ctiocb)
buf_ptr = (struct lpfc_dmabuf *) ctiocb-context3;
lpfc_mbuf_free(phba, buf_ptr-virt, buf_ptr-phys);
kfree(buf_ptr);
-   ctiocb-context1 = NULL;
+   ctiocb-context3 = NULL;
}
lpfc_sli_release_iocbq(phba, ctiocb);
return 0;
--
1.7.10.4




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


Re: [PATCH 7/7] scsi: Add 'eh_deadline' to limit SCSI EH runtime

2013-10-16 Thread James Bottomley
On Mon, 2013-07-01 at 08:50 +0200, Hannes Reinecke wrote:
 This patchs adds an 'eh_deadline' sysfs attribute to the scsi
 host which limits the overall runtime of the SCSI EH.
 The 'eh_deadline' value is stored in the now obsolete field
 'resetting'.
 When a command is failed the start time of the EH is stored
 in 'last_reset'. If the overall runtime of the SCSI EH is longer
 than last_reset + eh_deadline, the EH is short-circuited and
 falls through to issue a host reset only.

OK, so the specific problem with this one is that potentially it will
spend all its time mucking about with aborts (which most often time out
on non FC kit because of the issue problems) and then proceed to host
reset, which mostly does nothing for failing devices.

If you want to impose a deadline, then we need to spend only 50% of the
time attempting aborts and the rest of the time escalating the resets.

[...]
 diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
 index f43de1e..84369f2 100644
 --- a/drivers/scsi/scsi_error.c
 +++ b/drivers/scsi/scsi_error.c
 @@ -89,6 +89,18 @@ void scsi_schedule_eh(struct Scsi_Host *shost)
  }
  EXPORT_SYMBOL_GPL(scsi_schedule_eh);
  
 +static int scsi_host_eh_past_deadline(struct Scsi_Host *shost)
 +{
 + if (!shost-last_reset || !shost-eh_deadline)
 + return 0;
 +
 + if (time_before(jiffies,
 + shost-last_reset + shost-eh_deadline))
 + return 0;
 +
 + return 1;
 +}
 +

What about instead:

static int scsi_host_eh_past_deadline(struct Scsi_Host *shost, int percent) {
if (!shost-last_reset || !shost-eh_deadline)
return 0;

if (time_before(jiffies,
shost-last_reset + shost-eh_deadline * percent/100))
return 0;

return 1;
}

which allows us to have

if (scsi_host_eh_past_deadline(shost, 50)) {

in scsi_eh_abort_cmds()

if (scsi_host_eh_past_deadline(shost, 66) {

in scsi_eh_bus_device_reset()

say 83 in target reset, and 100 in bus reset.

Thus ensuring we at least get a crack at the reset chain?

James

--
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: Fix erratic device offline during EH

2013-10-16 Thread James Bottomley
On Mon, 2013-09-02 at 13:58 +0200, Hannes Reinecke wrote:
 Commit 18a4d0a22ed6c54b67af7718c305cd010f09ddf8
 (Handle disk devices which can not process medium access commands)
 was introduced to offline any device which cannot process medium
 access commands.
 However, commit 3eef6257de48ff84a5d98ca533685df8a3beaeb8
 (Reduce error recovery time by reducing use of TURs) reduced
 the number of TURs by sending it only on the first failing
 command, which might or might not be a medium access command.
 So in combination this results in an erratic device offlining
 during EH; if the command where the TUR was sent upon happens
 to be a medium access command the device will be set offline,
 if not everything proceeds as normal.
 
 So instead of checking the EH command in the -eh_action
 callback we should rather call -eh_action when we're
 about to finish the command _and_ have sent a TUR previously.
 This should then set the device offline as advertised.
 
 Cc: Martin K. Petersen martin.peter...@oracle.com
 Cc: Ewan Milne emi...@redhat.com
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/scsi/scsi_error.c | 28 +++-
  1 file changed, 19 insertions(+), 9 deletions(-)
 
 diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
 index abf0916..c88cb7e 100644
 --- a/drivers/scsi/scsi_error.c
 +++ b/drivers/scsi/scsi_error.c
 @@ -941,12 +941,6 @@ retry:
  
   scsi_eh_restore_cmnd(scmd, ses);
  
 - if (scmd-request-cmd_type != REQ_TYPE_BLOCK_PC) {
 - struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
 - if (sdrv-eh_action)
 - rtn = sdrv-eh_action(scmd, cmnd, cmnd_size, rtn);
 - }
 -
   return rtn;
  }
  
 @@ -964,6 +958,18 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
   return scsi_send_eh_cmnd(scmd, NULL, 0, scmd-device-eh_timeout, ~0);
  }
  
 +static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
 +{
 + static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
 +
 + if (scmd-request-cmd_type != REQ_TYPE_BLOCK_PC) {
 + struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
 + if (sdrv-eh_action)
 + rtn = sdrv-eh_action(scmd, tur_command, 6, rtn);

This is all a bit pointless.  You've altered eh_action so it's always
input an eh TUR command, so just eliminate the check of the eh command
and assume it's a TUR in the implementation (i.e. fix up sd.c)

Once that's done, I think the patch looks like the one below, is that
OK?

I still have qualms about the media access check because what can happen
is that we abort, TUR succeeds then the next Media access command fails,
we abort, TUR succeeds etc until the media access timeout goes off.  The
problem is that it never gets escalated to a reset which might fix the
condition.  However, this is beyond the scope of the current patch set.

James

---
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 83e591b..aef80f1 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -923,12 +923,6 @@ retry:
 
scsi_eh_restore_cmnd(scmd, ses);
 
-   if (scmd-request-cmd_type != REQ_TYPE_BLOCK_PC) {
-   struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
-   if (sdrv-eh_action)
-   rtn = sdrv-eh_action(scmd, cmnd, cmnd_size, rtn);
-   }
-
return rtn;
 }
 
@@ -946,6 +940,16 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
return scsi_send_eh_cmnd(scmd, NULL, 0, scmd-device-eh_timeout, ~0);
 }
 
+static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
+{
+   if (scmd-request-cmd_type != REQ_TYPE_BLOCK_PC) {
+   struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
+   if (sdrv-eh_action)
+   rtn = sdrv-eh_action(scmd, rtn);
+   }
+   return rtn;
+}
+
 /**
  * scsi_eh_finish_cmd - Handle a cmd that eh is finished with.
  * @scmd:  Original SCSI cmd that eh has finished.
@@ -1094,7 +1098,9 @@ static int scsi_eh_test_devices(struct list_head 
*cmd_list,
 
list_for_each_entry_safe(scmd, next, cmd_list, eh_entry)
if (scmd-device == sdev) {
-   if (finish_cmds)
+   if (finish_cmds 
+   (try_stu ||
+scsi_eh_action(scmd, SUCCESS) == SUCCESS))
scsi_eh_finish_cmd(scmd, done_q);
else
list_move_tail(scmd-eh_entry, work_q);
@@ -1208,7 +1214,8 @@ static int scsi_eh_stu(struct Scsi_Host *shost,
!scsi_eh_tur(stu_scmd)) {
list_for_each_entry_safe(scmd, next,
  work_q, eh_entry) {
-   if (scmd-device == sdev)
+   

Re: [Bug] 12.864681 BUG: lock held when returning to user space!

2013-10-16 Thread James Bottomley
On Tue, 2013-10-08 at 09:45 -0400, Douglas Gilbert wrote:
 On 13-10-08 02:44 AM, vaughan wrote:
  Hi Madper,
 
  CC to Douglas to get comments.
  I use the rw_semaphore o_sem to protect excl open, introduced in commit
  15b06f9a02406e5460001db6d5af5c738cd3d4e7 since v3.12-rc1.
  Is it forbidden to do like that in kernel?...
 
 It appears you can not (allow sg_open() to hold a semaphore
 then return to the user space). So you will need to do some
 rework on that patch or revert it.

OK, there being no reply on this, I'll do the revert ... that's all four
patches, correct?

James


--
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


kernel cant access SATA adapter device

2013-10-16 Thread Robert Story
Hi,

I've got a SATA adapter for a SD card in a Dell Poweredge R610. The BIOS
can see and boot the sdcard, (to Windows, or using syslinux/extlinux), but
when it hands over control to the Linux kernel, the kernel cannot access it.

Here's an excerpt from dmesg:

scsi 0:0:2:0: Direct-Access ATA  FC-1307 SD to CF 1.1  PQ: 0 ANSI: 5
sd 0:0:2:0: Attached scsi generic sg3 type 0
mptsas: ioc0: mptsas_free_fw_event: kfree (fw_event=0x8801ab1ad8c0)
sd 0:0:2:0: [sdc] Spinning up disk .not responding...
sd 0:0:2:0: [sdc] READ CAPACITY(16) failed
sd 0:0:2:0: [sdc] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
sd 0:0:2:0: [sdc] Sense Key : Not Ready [current]
sd 0:0:2:0: [sdc] Add. Sense: Logical unit not ready, initializing command 
required
sd 0:0:2:0: [sdc] READ CAPACITY failed
sd 0:0:2:0: [sdc] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
sd 0:0:2:0: [sdc] Sense Key : Not Ready [current]
sd 0:0:2:0: [sdc] Add. Sense: Logical unit not ready, initializing command 
required
sd 0:0:2:0: [sdc] Test WP failed, assume Write Enabled
sd 0:0:2:0: [sdc] Asking for cache data failed
sd 0:0:2:0: [sdc] Assuming drive cache: write through

After booting and running 'sdparm --command=start /dev/sdc' I can get a
read capacity to work, but cannot access the drive (e.g. fdisk -l /dev/sdc).

If I put the SD card in a USB adapter, it works, and I was able to access
the SD card via the SD adapter in another machine. But our production
machines are dell's, so I really want to get it working there.

I've attached more complete debug info from booting and existing CentOS 6.4
install with the card installed, and a rdsosreport from an attempt to boot
Fedora 20 Alpha.

Any help or suggestions greatly appreciated.


Robert

--
Senior Software Engineer
Parsons Government Services , National Security  Defense Division
--
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/5] Updates for tcm_loop

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:12 +0200, Hannes Reinecke wrote:
 Hi Nic,
 
 here are some updates to tcm_loop I've done during ALUA testing.
 I've implemented a 'transport_state' attribute to simulate
 transport failure and added command abort callbacks.
 
 Hannes Reinecke (5):
   tcm_loop: Check for valid hba in tcm_loop_drop_nexus()
   tcm_loop: Implement transport offline
   tcm_loop: separate out tcm_loop_issue_tmr
   tcm_loop: TCQ and command abort support
   tcm_loop: Implement target reset
 
  drivers/target/loopback/tcm_loop.c | 233 
 +++--
  drivers/target/loopback/tcm_loop.h |   6 +
  include/target/target_core_base.h  |   1 +
  3 files changed, 204 insertions(+), 36 deletions(-)
 

Everything looks reasonable to me..  Applied to target-pending/for-next.

Thanks Hannes!

--nab

--
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 01/11] target core: rename (ex,im)plict - (ex,im)plicit

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_alua.c  | 110 
 -
  drivers/target/target_core_alua.h  |  20 +++---
  drivers/target/target_core_configfs.c  |  26 
  drivers/target/target_core_device.c|   6 +-
  drivers/target/target_core_file.c  |   2 +-
  drivers/target/target_core_pr.c|  24 +++
  drivers/target/target_core_spc.c   |   6 +-
  drivers/target/target_core_transport.c |   4 +-
  drivers/target/target_core_ua.h|   2 +-
  include/target/target_core_base.h  |   2 +-
  10 files changed, 101 insertions(+), 101 deletions(-)
 

Applied to target-pending/for-next.

Thanks Hannes!

--nab

--
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/11] target_core_alua: Store supported ALUA states

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 The supported ALUA states might be different for individual
 devices, so store it in a separate field.
 
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_alua.c | 14 --
  drivers/target/target_core_alua.h | 11 +++
  include/target/target_core_base.h |  1 +
  3 files changed, 20 insertions(+), 6 deletions(-)
 
 diff --git a/drivers/target/target_core_alua.c 
 b/drivers/target/target_core_alua.c
 index 8297d37..255e83c 100644
 --- a/drivers/target/target_core_alua.c
 +++ b/drivers/target/target_core_alua.c
 @@ -117,12 +117,7 @@ target_emulate_report_target_port_groups(struct se_cmd 
 *cmd)
   /*
* Set supported ASYMMETRIC ACCESS State bits
*/
 - buf[off] = 0x80; /* T_SUP */
 - buf[off] |= 0x40; /* O_SUP */
 - buf[off] |= 0x8; /* U_SUP */
 - buf[off] |= 0x4; /* S_SUP */
 - buf[off] |= 0x2; /* AN_SUP */
 - buf[off++] |= 0x1; /* AO_SUP */
 + buf[off++] |= tg_pt_gp-tg_pt_gp_alua_supported_states;
   /*
* TARGET PORT GROUP
*/
 @@ -1367,6 +1362,13 @@ struct t10_alua_tg_pt_gp 
 *core_alua_allocate_tg_pt_gp(struct se_device *dev,
   tg_pt_gp-tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
   tg_pt_gp-tg_pt_gp_implicit_trans_secs = 
 ALUA_DEFAULT_IMPLICIT_TRANS_SECS;
  
 + /*
 +  * Enable all supported states
 +  */
 + tg_pt_gp-tg_pt_gp_alua_supported_states =
 + ALUA_T_SUP | ALUA_O_SUP | \
 + ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
 +
   if (def_group) {
   spin_lock(dev-t10_alua.tg_pt_gps_lock);
   tg_pt_gp-tg_pt_gp_id =
 diff --git a/drivers/target/target_core_alua.h 
 b/drivers/target/target_core_alua.h
 index 74cf0c0..e826a65 100644
 --- a/drivers/target/target_core_alua.h
 +++ b/drivers/target/target_core_alua.h
 @@ -23,6 +23,17 @@
  #define ALUA_ACCESS_STATE_TRANSITION 0xf
  
  /*
 + * from spc4r36j section 6.37 Table 306
 + */
 +#define ALUA_T_SUP   0x80
 +#define ALUA_O_SUP   0x40
 +#define ALUA_LBD_SUP 0x10
 +#define ALUA_U_SUP   0x08
 +#define ALUA_S_SUP   0x04
 +#define ALUA_AN_SUP  0x02
 +#define ALUA_AO_SUP  0x01
 +
 +/*

How about making these the supported bits, TPGS mode, and ALUA access
state definitions common between target_core_alua.c and
scsi_dh_alua.c..?

--nab

--
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/11] target_core_alua: Make supported states configurable

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_configfs.c | 50 
 +++
  1 file changed, 50 insertions(+)
 
 diff --git a/drivers/target/target_core_configfs.c 
 b/drivers/target/target_core_configfs.c
 index d4c28a3..53e9e00 100644
 --- a/drivers/target/target_core_configfs.c
 +++ b/drivers/target/target_core_configfs.c
 @@ -2131,6 +2131,55 @@ static ssize_t 
 target_core_alua_tg_pt_gp_store_attr_alua_access_type(
  SE_DEV_ALUA_TG_PT_ATTR(alua_access_type, S_IRUGO | S_IWUSR);
  
  /*
 + * alua_supported_states
 + */
 +static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_supported_states(
 + struct t10_alua_tg_pt_gp *tg_pt_gp,
 + char *page)
 +{
 + return sprintf(page, %02x\n,
 + tg_pt_gp-tg_pt_gp_alua_supported_states);
 +}
 +
 +static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_supported_states(
 + struct t10_alua_tg_pt_gp *tg_pt_gp,
 + const char *page,
 + size_t count)
 +{
 + unsigned long tmp;
 + int new_states, valid_states, ret;
 +
 + if (!tg_pt_gp-tg_pt_gp_valid_id) {
 + pr_err(Unable to do set supported ALUA states on non
 +  valid tg_pt_gp ID: %hu\n,
 + tg_pt_gp-tg_pt_gp_valid_id);
 + return -EINVAL;
 + }
 +
 + ret = strict_strtoul(page, 0, tmp);
 + if (ret  0) {
 + pr_err(Unable to extract new supported ALUA states
 +  from %s\n, page);
 + return -EINVAL;
 + }
 + new_states = (int)tmp;
 + valid_states = ALUA_T_SUP | ALUA_O_SUP | ALUA_LBD_SUP | \
 + ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
 +
 +
 + if (new_states  ~valid_states) {
 + pr_err(Illegal supported ALUA states: 0x%02x\n,
 + new_states);
 + return -EINVAL;
 + }
 +
 + tg_pt_gp-tg_pt_gp_alua_supported_states = new_states;
 + return count;
 +}
 +
 +SE_DEV_ALUA_TG_PT_ATTR(alua_supported_states, S_IRUGO | S_IWUSR);
 +
 +/*
   * alua_write_metadata
   */
  static ssize_t target_core_alua_tg_pt_gp_show_attr_alua_write_metadata(
 @@ -2350,6 +2399,7 @@ static struct configfs_attribute 
 *target_core_alua_tg_pt_gp_attrs[] = {
   target_core_alua_tg_pt_gp_alua_access_state.attr,
   target_core_alua_tg_pt_gp_alua_access_status.attr,
   target_core_alua_tg_pt_gp_alua_access_type.attr,
 + target_core_alua_tg_pt_gp_alua_supported_states.attr,
   target_core_alua_tg_pt_gp_alua_write_metadata.attr,
   target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
   target_core_alua_tg_pt_gp_trans_delay_msecs.attr,

I'm thinking this might be better served by individual attributes
representing the seven supported ALUA states, instead of a single
attribute representing them all..

That would certainly make it easier for userspace to manipulate..

--nab

--
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/11] target_core_alua: Validate ALUA state transition

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 As we now can modify the list of supported states we need to
 validate the requested ALUA state when doing a state transition.
 
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---

Looks good.

--nab

  drivers/target/target_core_alua.c | 85 
 ++-
  1 file changed, 56 insertions(+), 29 deletions(-)
 
 diff --git a/drivers/target/target_core_alua.c 
 b/drivers/target/target_core_alua.c
 index a16115e..a420778 100644
 --- a/drivers/target/target_core_alua.c
 +++ b/drivers/target/target_core_alua.c
 @@ -41,7 +41,8 @@
  #include target_core_alua.h
  #include target_core_ua.h
  
 -static sense_reason_t core_alua_check_transition(int state, int *primary);
 +static sense_reason_t core_alua_check_transition(int state, int valid,
 +  int *primary);
  static int core_alua_set_tg_pt_secondary_state(
   struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
   struct se_port *port, int explicit, int offline);
 @@ -210,7 +211,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
   unsigned char *ptr;
   sense_reason_t rc = TCM_NO_SENSE;
   u32 len = 4; /* Skip over RESERVED area in header */
 - int alua_access_state, primary = 0;
 + int alua_access_state, primary = 0, valid_states;
   u16 tg_pt_id, rtpi;
  
   if (!l_port)
 @@ -252,6 +253,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
   rc = TCM_UNSUPPORTED_SCSI_OPCODE;
   goto out;
   }
 + valid_states = l_tg_pt_gp-tg_pt_gp_alua_supported_states;
  
   ptr = buf[4]; /* Skip over RESERVED area in header */
  
 @@ -263,7 +265,8 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
* the state is a primary or secondary target port asymmetric
* access state.
*/
 - rc = core_alua_check_transition(alua_access_state, primary);
 + rc = core_alua_check_transition(alua_access_state,
 + valid_states, primary);
   if (rc) {
   /*
* If the SET TARGET PORT GROUPS attempts to establish
 @@ -614,21 +617,57 @@ out:
   return 0;
  }
  
 +static char *core_alua_dump_state(int state)
 +{
 + switch (state) {
 + case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
 + return Active/Optimized;
 + case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
 + return Active/NonOptimized;
 + case ALUA_ACCESS_STATE_STANDBY:
 + return Standby;
 + case ALUA_ACCESS_STATE_UNAVAILABLE:
 + return Unavailable;
 + case ALUA_ACCESS_STATE_OFFLINE:
 + return Offline;
 + case ALUA_ACCESS_STATE_TRANSITION:
 + return Transitioning;
 + default:
 + return Unknown;
 + }
 +
 + return NULL;
 +}
 +
  /*
   * Check implicit and explicit ALUA state change request.
   */
  static sense_reason_t
 -core_alua_check_transition(int state, int *primary)
 +core_alua_check_transition(int state, int valid, int *primary)
  {
 + /*
 +  * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are
 +  * defined as primary target port asymmetric access states.
 +  */
   switch (state) {
   case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
 + if (!(valid  ALUA_AO_SUP))
 + goto not_supported;
 + *primary = 1;
 + break;
   case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
 + if (!(valid  ALUA_AN_SUP))
 + goto not_supported;
 + *primary = 1;
 + break;
   case ALUA_ACCESS_STATE_STANDBY:
 + if (!(valid  ALUA_S_SUP))
 + goto not_supported;
 + *primary = 1;
 + break;
   case ALUA_ACCESS_STATE_UNAVAILABLE:
 - /*
 -  * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are
 -  * defined as primary target port asymmetric access states.
 -  */
 + if (!(valid  ALUA_U_SUP))
 + goto not_supported;
   *primary = 1;
   break;
   case ALUA_ACCESS_STATE_OFFLINE:
 @@ -636,6 +675,8 @@ core_alua_check_transition(int state, int *primary)
* OFFLINE state is defined as a secondary target port
* asymmetric access state.
*/
 + if (!(valid  ALUA_O_SUP))
 + goto not_supported;
   *primary = 0;
   break;
   default:
 @@ -644,26 +685,11 @@ core_alua_check_transition(int state, int *primary)
   }
  
   return 0;
 -}
  
 -static char *core_alua_dump_state(int state)
 -{
 - switch (state) {
 - case ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED:
 - return Active/Optimized;
 - case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
 - 

Re: [PATCH 07/11] target_core_alua: Allocate ALUA metadata on demand

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 We should only allocate ALUA metadata if we're actually going
 to write them.
 
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_alua.c | 70 
 +--
  drivers/target/target_core_alua.h |  3 ++
  include/target/target_core_base.h |  3 --
  3 files changed, 34 insertions(+), 42 deletions(-)
 

Looks reasonable to me..

--nab

 diff --git a/drivers/target/target_core_alua.c 
 b/drivers/target/target_core_alua.c
 index a420778..b1d08bf 100644
 --- a/drivers/target/target_core_alua.c
 +++ b/drivers/target/target_core_alua.c
 @@ -762,16 +762,22 @@ static int core_alua_write_tpg_metadata(
   */
  static int core_alua_update_tpg_primary_metadata(
   struct t10_alua_tg_pt_gp *tg_pt_gp,
 - int primary_state,
 - unsigned char *md_buf)
 + int primary_state)
  {
 + unsigned char *md_buf;
   struct t10_wwn *wwn = tg_pt_gp-tg_pt_gp_dev-t10_wwn;
   char path[ALUA_METADATA_PATH_LEN];
 - int len;
 + int len, rc;
 +
 + md_buf = kzalloc(ALUA_MD_BUF_LEN, GFP_KERNEL);
 + if (!md_buf) {
 + pr_err(Unable to allocate buf for ALUA metadata\n);
 + return -ENOMEM;
 + }
  
   memset(path, 0, ALUA_METADATA_PATH_LEN);
  
 - len = snprintf(md_buf, tg_pt_gp-tg_pt_gp_md_buf_len,
 + len = snprintf(md_buf, ALUA_MD_BUF_LEN,
   tg_pt_gp_id=%hu\n
   alua_access_state=0x%02x\n
   alua_access_status=0x%02x\n,
 @@ -782,14 +788,15 @@ static int core_alua_update_tpg_primary_metadata(
   /var/target/alua/tpgs_%s/%s, wwn-unit_serial[0],
   config_item_name(tg_pt_gp-tg_pt_gp_group.cg_item));
  
 - return core_alua_write_tpg_metadata(path, md_buf, len);
 + rc = core_alua_write_tpg_metadata(path, md_buf, len);
 + kfree(md_buf);
 + return rc;
  }
  
  static int core_alua_do_transition_tg_pt(
   struct t10_alua_tg_pt_gp *tg_pt_gp,
   struct se_port *l_port,
   struct se_node_acl *nacl,
 - unsigned char *md_buf,
   int new_state,
   int explicit)
  {
 @@ -877,8 +884,7 @@ static int core_alua_do_transition_tg_pt(
*/
   if (tg_pt_gp-tg_pt_gp_write_metadata) {
   mutex_lock(tg_pt_gp-tg_pt_gp_md_mutex);
 - core_alua_update_tpg_primary_metadata(tg_pt_gp,
 - new_state, md_buf);
 + core_alua_update_tpg_primary_metadata(tg_pt_gp, new_state);
   mutex_unlock(tg_pt_gp-tg_pt_gp_md_mutex);
   }
   /*
 @@ -909,19 +915,12 @@ int core_alua_do_port_transition(
   struct t10_alua_lu_gp *lu_gp;
   struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem;
   struct t10_alua_tg_pt_gp *tg_pt_gp;
 - unsigned char *md_buf;
   int primary, valid_states;
  
   valid_states = l_tg_pt_gp-tg_pt_gp_alua_supported_states;
   if (core_alua_check_transition(new_state, valid_states, primary) != 0)
   return -EINVAL;
  
 - md_buf = kzalloc(l_tg_pt_gp-tg_pt_gp_md_buf_len, GFP_KERNEL);
 - if (!md_buf) {
 - pr_err(Unable to allocate buf for ALUA metadata\n);
 - return -ENOMEM;
 - }
 -
   local_lu_gp_mem = l_dev-dev_alua_lu_gp_mem;
   spin_lock(local_lu_gp_mem-lu_gp_mem_lock);
   lu_gp = local_lu_gp_mem-lu_gp;
 @@ -939,10 +938,9 @@ int core_alua_do_port_transition(
* success.
*/
   core_alua_do_transition_tg_pt(l_tg_pt_gp, l_port, l_nacl,
 - md_buf, new_state, explicit);
 + new_state, explicit);
   atomic_dec(lu_gp-lu_gp_ref_cnt);
   smp_mb__after_atomic_dec();
 - kfree(md_buf);
   return 0;
   }
   /*
 @@ -992,7 +990,7 @@ int core_alua_do_port_transition(
* success.
*/
   core_alua_do_transition_tg_pt(tg_pt_gp, port,
 - nacl, md_buf, new_state, explicit);
 + nacl, new_state, explicit);
  
   spin_lock(dev-t10_alua.tg_pt_gps_lock);
   atomic_dec(tg_pt_gp-tg_pt_gp_ref_cnt);
 @@ -1014,7 +1012,6 @@ int core_alua_do_port_transition(
  
   atomic_dec(lu_gp-lu_gp_ref_cnt);
   smp_mb__after_atomic_dec();
 - kfree(md_buf);
   return 0;
  }
  
 @@ -1023,13 +1020,18 @@ int core_alua_do_port_transition(
   */
  static int core_alua_update_tpg_secondary_metadata(
   struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem,
 - struct se_port *port,
 - unsigned char *md_buf,
 - u32 md_buf_len)
 + struct se_port *port)
  {
 + unsigned char *md_buf;
   struct se_portal_group *se_tpg = port-sep_tpg;
   char path[ALUA_METADATA_PATH_LEN], wwn[ALUA_SECONDARY_METADATA_WWN_LEN];
 - int len;
 + int len, rc;
 +
 

Re: [PATCH][SCSI] megaraid_sas: Fix synchronization problem between sysPD IO path and AEN path

2013-10-16 Thread James Bottomley
On Wed, 2013-10-16 at 17:04 +0530, sumit.sax...@lsi.com wrote:
 There is syncronization problem between sysPD IO path and AEN path. Driver 
 maintains instance-pd_list[] array, which will get updated(by calling 
 function megasas_get_pd_list[]), whenever any of below events occurs-
 
 MR_EVT_PD_INSERTED
 MR_EVT_PD_REMOVED
 MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED
 MR_EVT_FOREIGN_CFG_IMPORTED
 
 At same time running sysPD IO will be accessing the same array 
 instance-pd_list[], which is getting updated in AEN path, because
 of this IO may not get correct PD info from instance-pd_list[] array.
 
 Signed-off-by: Adam Radford adam.radf...@lsi.com
 Signed-off-by: Sumit Saxena sumit.sax...@lsi.com

Explain the signoff chain: is this a joinly authored patch?

James

--
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] Fix device detection issues with mvsas driver

2013-10-16 Thread James Bottomley
On Tue, 2013-10-15 at 19:40 -0700, Praveen Murali wrote:
 Yes, I checked that today and was meaning to ask you about it. :)

Ideally, I need someone from Marvell to ack it ... can you prod them?

Thanks,

James


--
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


Help us complete this charity project, reply for detail!!!

2013-10-16 Thread Mr. Allen Violet Large
--
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/11] target_core_alua: Use workqueue for ALUA transitioning

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 Use a workqueue for processing ALUA state transitions; this allows
 us to process implicit delay properly.
 
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_alua.c | 174 
 +++---
  include/target/target_core_base.h |   4 +
  2 files changed, 128 insertions(+), 50 deletions(-)
 

SNIP

 +static int core_alua_do_transition_tg_pt(
 + struct t10_alua_tg_pt_gp *tg_pt_gp,
 + int new_state,
 + int explicit)
 +{
 + struct se_device *dev = tg_pt_gp-tg_pt_gp_dev;
 + DECLARE_COMPLETION_ONSTACK(wait);
 +
 + /* Nothing to be done here */
 + if (atomic_read(tg_pt_gp-tg_pt_gp_alua_access_state) == new_state)
 + return 0;
 +
 + if (new_state == ALUA_ACCESS_STATE_TRANSITION)
 + return -EAGAIN;
 +
 + /*
 +  * Flush any pending transitions
 +  */
 + if (!explicit  tg_pt_gp-tg_pt_gp_implicit_trans_secs 
 + atomic_read(tg_pt_gp-tg_pt_gp_alua_access_state) ==
 + ALUA_ACCESS_STATE_TRANSITION) {
 + /* Just in case */
 + tg_pt_gp-tg_pt_gp_alua_pending_state = new_state;
 + tg_pt_gp-tg_pt_gp_transition_complete = wait;
 + flush_delayed_work(tg_pt_gp-tg_pt_gp_transition_work);
 + wait_for_completion(wait);
 + tg_pt_gp-tg_pt_gp_transition_complete = NULL;
 + return 0;
 + }
 +
 + /*
 +  * Save the old primary ALUA access state, and set the current state
 +  * to ALUA_ACCESS_STATE_TRANSITION.
 +  */
 + tg_pt_gp-tg_pt_gp_alua_previous_state =
 + atomic_read(tg_pt_gp-tg_pt_gp_alua_access_state);
 + tg_pt_gp-tg_pt_gp_alua_pending_state = new_state;
 +
 + atomic_set(tg_pt_gp-tg_pt_gp_alua_access_state,
 + ALUA_ACCESS_STATE_TRANSITION);
 + tg_pt_gp-tg_pt_gp_alua_access_status = (explicit) ?
 + ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG :
 + ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA;
 +
 + /*
 +  * Check for the optional ALUA primary state transition delay
 +  */
 + if (tg_pt_gp-tg_pt_gp_trans_delay_msecs != 0)
 + msleep_interruptible(tg_pt_gp-tg_pt_gp_trans_delay_msecs);
 +
 + /*
 +  * Take a reference for workqueue item
 +  */
 + spin_lock(dev-t10_alua.tg_pt_gps_lock);
 + atomic_inc(tg_pt_gp-tg_pt_gp_ref_cnt);
 + smp_mb__after_atomic_inc();
 + spin_unlock(dev-t10_alua.tg_pt_gps_lock);
 +
 + if (!explicit  tg_pt_gp-tg_pt_gp_implicit_trans_secs) {
 + unsigned long transition_tmo;
 +
 + transition_tmo = tg_pt_gp-tg_pt_gp_implicit_trans_secs * HZ;
 + queue_delayed_work(tg_pt_gp-tg_pt_gp_dev-tmr_wq,
 +tg_pt_gp-tg_pt_gp_transition_work,
 +transition_tmo);
 + } else {
 + tg_pt_gp-tg_pt_gp_transition_complete = wait;
 + queue_delayed_work(tg_pt_gp-tg_pt_gp_dev-tmr_wq,
 +tg_pt_gp-tg_pt_gp_transition_work, 0);
 + wait_for_completion(wait);
 + tg_pt_gp-tg_pt_gp_transition_complete = NULL;
 + }

Mmm, the trans_delay_msecs delay seems a bit out of place now..

How about dropping it's usage with msleep_interruptible() above, and
instead combining it with the delay passed into queue_delayed_work()..?

--nab


--
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 00/11] target_core_mod: ALUA updates

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 Hi Nic,
 
 here are some updates to TCM ALUA handling. Apart from some
 minor fixes and spellchecks the main features are:
 - Make supported states configurable:
   We should make the list of supported ALUA states configurable,
   as some setups would possibly like to support a small subset
   of ALUA states only.
 - Asynchronous transitioning: I've switched 'transitioning'
   handling to use a workqueue, that should allow us to simulate
   asynchronous transitioning modes. IE TCM should now be capable
   of handling requests while in transitioning, and properly terminate
   these with the correct sense code.
 - Include target device descriptor in VPD page 83
   For the ALUA device handler we'd need to identify the target device
   where a given target port belongs to. So include the respective
   values in the VPD page.
 
 Hannes Reinecke (11):
   target core: rename (ex,im)plict - (ex,im)plicit
   target_core_alua: Store supported ALUA states
   target_core_alua: Make supported states configurable
   target_core_alua: Rename ALUA_ACCESS_STATE_OPTIMIZED
   target_core_alua: spellcheck
   target_core_alua: Validate ALUA state transition
   target_core_alua: Allocate ALUA metadata on demand
   target_core_alua: store old and pending ALUA state
   target_core_alua: Use workqueue for ALUA transitioning
   target_core: simplify scsi_name_len calculation
   target_core_spc: Include target device descriptor in VPD page 83
 

Hey Hannes,

It looks like Patches #10  #11 did not make it to the list.

Care to address the minor comments on the others and repost a -v2 with
the missing ones..?

--nab

--
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


How are you doing.

2013-10-16 Thread Brice

Dear friend  

I am Mr.Axel Brice a banker from one of the international bank here in my 
country. Although the world is  spherical and hard place to met people because 
you don't know who to trust or believe, but I have developed my trust to you to 
confide this confidential business proposal. 

4 years ago, most of the African Politicians used our bank to launder fund to 
overseas through the help of their Political advisers, I find out what was 
going because these days some of the fund where stock for politicians, I was 
able to divert ($15.2M) to an escrow account that belong to unknown person.

So i will like you to act as the depositor of the fund because the bank do not 
know the owner of the fund and also the claim is legal as i have make all the 
good arrangement to transfer the fund to foreign account.

Thanks 
Mr. Axel Brice
--
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] Fix device detection issues with mvsas driver

2013-10-16 Thread Praveen Murali

Hi Xiang, Can you please take a look at the attached patch and ack it?

Thanks,
Praveen

On 10/16/2013 02:45 PM, James Bottomley wrote:

On Tue, 2013-10-15 at 19:40 -0700, Praveen Murali wrote:

Yes, I checked that today and was meaning to ask you about it. :)

Ideally, I need someone from Marvell to ack it ... can you prod them?

Thanks,

James




From 6ad9cf691f9d11e8c6de332efc35bd945c0f2840 Mon Sep 17 00:00:00 2001
From: Praveen Murali pmur...@logicube.com
Date: Thu, 21 Jun 2012 09:57:03 -0700
Subject: [PATCH v2] Fix mvsas SATA disk detection issues

 I am using the Marvell SAS HBA (MV64460/64461/64462 System Controller,
Revision B (rev 01)), on a system running Ubuntu 12.04 stock kernel. And
i am seeing some drive detection issues with SATA drives, mostly during
hotplugging the drives; the issue gets exaggerated when we keep removing
and plugging in drives.

From dmesg, after starting the LibATA debugs, it looks like the
ata_eh_revalidate_and_attach fails because ata_dev_read_id fails to get
the IDENTIFY command response. I see both IDENTIFYs aborted, assuming
NODEV for all these drives that go undetected. At this point, if I
unload and reload the mvsas driver, these drives detect fine. So, I
hooked up a SATA analyzer between the HBA and one of the drives, and
restarted the test. From what I can see, even though the drive responds
to the IDENTIFY command, the upper layer detects an error and discards
the response. On further debugging it was evident that the error was
being detected in the FIS.

 After going thru the mvsas driver, I see that during init the driver 
allocates a DMA area for an FIS pool (for as many as 33 FIS's) and initializes 
it to 0. And each ATA command is allocated a FIS area from this pool during
the command prep; but its never cleared.

The fix is to cleanup and prepare the FIS index before issuing the ATA
command (during prep: mvs_task_prep_ata).
---
 drivers/scsi/mvsas/mv_sas.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index a4884a5..73d9816 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -458,6 +458,11 @@ static int mvs_task_prep_ata(struct mvs_info *mvi,
 			mvi_dev-device_id);
 		return -EBUSY;
 	}
+
+	/* cleanup and prepare the allocated FIS index */
+	memset( SATA_RECEIVED_D2H_FIS(mvi_dev-taskfileset), 0, 
+sizeof(struct dev_to_host_fis) );
+
 	slot = mvi-slot_info[tag];
 	slot-tx = mvi-tx_prod;
 	del_q = TXQ_MODE_I | tag |
-- 
1.7.10



Re: [PATCH 1/2] target_core_alua: Referrals infrastructure

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:25 +0200, Hannes Reinecke wrote:
 Add infrastructure for referrals.
 
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_alua.c | 151 
 ++
  drivers/target/target_core_alua.h |   4 +-
  drivers/target/target_core_configfs.c |  12 ++-
  drivers/target/target_core_device.c   |   2 +
  drivers/target/target_core_sbc.c  |   5 +-
  drivers/target/target_core_spc.c  |  20 +
  include/scsi/scsi.h   |   1 +
  include/target/target_core_base.h |  18 
  8 files changed, 209 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/target/target_core_alua.c 
 b/drivers/target/target_core_alua.c
 index 166bee6..8f66146 100644
 --- a/drivers/target/target_core_alua.c
 +++ b/drivers/target/target_core_alua.c
 @@ -56,6 +56,75 @@ static LIST_HEAD(lu_gps_list);
  struct t10_alua_lu_gp *default_lu_gp;
  
  /*
 + * REPORT REFERRALS
 + *
 + * See sbc3r35 section 5.23
 + */
 +sense_reason_t
 +target_emulate_report_referrals(struct se_cmd *cmd)
 +{
 + struct se_device *dev = cmd-se_dev;
 + struct t10_alua_lba_map *map;
 + struct t10_alua_lba_map_member *map_mem;
 + unsigned char *buf;
 + u32 rd_len = 0, off;
 +
 + if (cmd-data_length  4) {
 + pr_warn(REPORT REFERRALS allocation length %u too
 +  small\n, cmd-data_length);
 + return TCM_INVALID_CDB_FIELD;
 + }
 +
 + buf = transport_kmap_data_sg(cmd);
 + if (!buf)
 + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 +
 + off = 4;
 + spin_lock(dev-t10_alua.lba_map_lock);
 + if (list_empty(dev-t10_alua.lba_map_list)) {
 + spin_unlock(dev-t10_alua.lba_map_lock);
 + transport_kunmap_data_sg(cmd);
 +
 + return TCM_UNSUPPORTED_SCSI_OPCODE;
 + }
 +
 + list_for_each_entry(map, dev-t10_alua.lba_map_list,
 + lba_map_list) {
 + int desc_num = off + 3;
 + int pg_num;
 +
 + off += 4;
 + put_unaligned_be64(map-lba_map_first_lba, buf[off]);
 + off += 8;
 + put_unaligned_be64(map-lba_map_last_lba, buf[off]);
 + off += 8;
 + rd_len += 20;
 + pg_num = 0;
 + list_for_each_entry(map_mem, map-lba_map_mem_list,
 + lba_map_mem_list) {
 + buf[off++] = map_mem-lba_map_mem_alua_state  0x0f;
 + off++;
 + buf[off++] = (map_mem-lba_map_mem_alua_pg_id  8)  
 0xff;
 + buf[off++] = (map_mem-lba_map_mem_alua_pg_id  0xff);
 + rd_len += 4;
 + pg_num++;
 + }
 + buf[desc_num] = pg_num;
 + }
 + spin_unlock(dev-t10_alua.lba_map_lock);
 +

For both of these list walks, there needs to be a check against offset
vs. -data_length to know when the available payload length has been
exhausted..

 + /*
 +  * Set the RETURN DATA LENGTH set in the header of the DataIN Payload
 +  */
 + put_unaligned_be16(rd_len, buf[2]);
 +
 + transport_kunmap_data_sg(cmd);
 +
 + target_complete_cmd(cmd, GOOD);
 + return 0;
 +}
 +
 +/*
   * REPORT_TARGET_PORT_GROUPS
   *
   * See spc4r17 section 6.27
 @@ -389,6 +458,80 @@ static inline int core_alua_state_nonoptimized(
   return 0;
  }
  
 +static inline int core_alua_state_lba_dependent(
 + struct se_cmd *cmd,
 + struct t10_alua_tg_pt_gp *tg_pt_gp,
 + u8 *alua_ascq)
 +{
 + struct se_device *dev = cmd-se_dev;
 + u32 segment_size, segment_mult, sectors;
 + u64 lba;
 +
 + /* Only need to check for cdb actually containing LBAs */
 + if (!cmd-se_cmd_flags  SCF_SCSI_DATA_CDB)
 + return 0;
 +
 + spin_lock(dev-t10_alua.lba_map_lock);
 + segment_size = dev-t10_alua.lba_map_segment_size;
 + segment_mult = dev-t10_alua.lba_map_segment_multiplier;
 + sectors = cmd-data_length / dev-dev_attrib.block_size;
 +
 + lba = cmd-t_task_lba;
 + while (lba  cmd-t_task_lba + sectors) {
 + struct t10_alua_lba_map *cur_map = NULL, *map;
 + struct t10_alua_lba_map_member *map_mem;
 +
 + list_for_each_entry(map, dev-t10_alua.lba_map_list,
 + lba_map_list) {
 + u64 start_lba, last_lba;
 + u64 first_lba = map-lba_map_first_lba;
 +
 + if (segment_mult) {
 + start_lba = lba % (segment_size * segment_mult);
 + last_lba = first_lba + segment_size - 1;
 + if (start_lba = first_lba 
 + start_lba = last_lba) {
 + lba += segment_size;
 + cur_map = map;
 + break;
 + }
 +

Re: [PATCH] target: Pass through I/O topology for block backstores

2013-10-16 Thread Andy Grover

On 10/12/2013 01:08 AM, Christoph Hellwig wrote:

On Fri, Oct 11, 2013 at 11:52:53AM -0700, Andy Grover wrote:

It seemed better to me to keep the munging from queue_limits values
to what the target core needed in the block backstore code, and not
use a block-specific structure in the backstore-core interface.

It looks like a few includes of blkdev.h slipped into target core,
but these can be removed safely -- lio core doesn't depend on the
block layer.

We could define a new struct to get the 4 values at once, but it
didn't seem worth it, esp. since two are only needed by
emulate_readcapacity16, and the other two only by emulate_evpd_b0.


I really don't like the influx of methods.  But given thsat you have
done the work I'd say merge your patch for now and then we can later see
if we can come up with something more elegant.


Nick, any cleaner ways to implement this come to mind? Happy to respin.

If not, please apply.

Regards -- Andy

--
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] 12.864681 BUG: lock held when returning to user space!

2013-10-16 Thread Douglas Gilbert

On 13-10-16 09:24 AM, James Bottomley wrote:

On Tue, 2013-10-08 at 09:45 -0400, Douglas Gilbert wrote:

On 13-10-08 02:44 AM, vaughan wrote:

Hi Madper,

CC to Douglas to get comments.
I use the rw_semaphore o_sem to protect excl open, introduced in commit
15b06f9a02406e5460001db6d5af5c738cd3d4e7 since v3.12-rc1.
Is it forbidden to do like that in kernel?...


It appears you can not (allow sg_open() to hold a semaphore
then return to the user space). So you will need to do some
rework on that patch or revert it.


OK, there being no reply on this, I'll do the revert ... that's all four
patches, correct?


That seems to be the case. Vaughan acknowledged the
problem and forwarded it to me 8 days ago. Yes, it
seems to be a no-no to hold a any kernel semaphore
when returning to the user space; in this case from
sg_open(). I was hoping a revised patch might
appear from Vaughan but to date that has not been
the case. So with only a few weeks to go before
lk 3.12 is released, reverting the whole 4 patches
in that series seems to be the safest course.

Also without a new patch from Vaughan in the next few
weeks he may also miss the opportunity of getting
his improved O_EXCL logic into the lk 3.13 series.


Thinking about how to solve this problem: a field could
be added to 'struct sg_device' with one of three states:
no_opens, non_excl_opens and excl_open. It could be
manipulated by sg_open() and sg_release() like a
read-write semaphore. And the faulty 'struct
rw_semaphore o_sem' in sg_device could be replaced by a
normal semaphore to protect the manipulation of the new
three-state field.

Doug Gilbert


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


Re: [PATCH 2/2] target_core_alua: Referrals configfs integration

2013-10-16 Thread Nicholas A. Bellinger
On Wed, 2013-10-16 at 09:25 +0200, Hannes Reinecke wrote:
 Referrals need an LBA map, which needs to be kept
 consistent across all target port groups. So
 instead of tying the map to the target port groups
 I've implemented a single attribute containing the
 entire map.
 
 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_alua.c  | 101 +++
  drivers/target/target_core_alua.h  |   8 ++
  drivers/target/target_core_configfs.c  | 171 
 +
  drivers/target/target_core_device.c|   1 +
  drivers/target/target_core_transport.c |  28 +-
  5 files changed, 308 insertions(+), 1 deletion(-)
 
 diff --git a/drivers/target/target_core_alua.c 
 b/drivers/target/target_core_alua.c
 index 8f66146..9dd01ff 100644
 --- a/drivers/target/target_core_alua.c
 +++ b/drivers/target/target_core_alua.c
 @@ -1340,6 +1340,107 @@ static int core_alua_set_tg_pt_secondary_state(
   return 0;
  }
  
 +struct t10_alua_lba_map *
 +core_alua_allocate_lba_map(struct list_head *list,
 +u64 first_lba, u64 last_lba)
 +{
 + struct t10_alua_lba_map *lba_map;
 +
 + lba_map = kmem_cache_zalloc(t10_alua_lba_map_cache, GFP_KERNEL);
 + if (!lba_map) {
 + pr_err(Unable to allocate struct t10_alua_lba_map\n);
 + return ERR_PTR(-ENOMEM);
 + }
 + INIT_LIST_HEAD(lba_map-lba_map_mem_list);
 + lba_map-lba_map_first_lba = first_lba;
 + lba_map-lba_map_last_lba = last_lba;
 +
 + list_add_tail(lba_map-lba_map_list, list);
 + return lba_map;
 +}

This list_add_tail needs to be protected, no..?

 +
 +int
 +core_alua_allocate_lba_map_mem(struct t10_alua_lba_map *lba_map,
 +int pg_id, int state)
 +{
 + struct t10_alua_lba_map_member *lba_map_mem;
 +
 + list_for_each_entry(lba_map_mem, lba_map-lba_map_mem_list,
 + lba_map_mem_list) {
 + if (lba_map_mem-lba_map_mem_alua_pg_id == pg_id) {
 + pr_err(Duplicate pg_id %d in lba_map\n, pg_id);
 + return -EINVAL;
 + }
 + }
 +
 + lba_map_mem = kmem_cache_zalloc(t10_alua_lba_map_mem_cache, GFP_KERNEL);
 + if (!lba_map_mem) {
 + pr_err(Unable to allocate struct t10_alua_lba_map_mem\n);
 + return -ENOMEM;
 + }
 + lba_map_mem-lba_map_mem_alua_state = state;
 + lba_map_mem-lba_map_mem_alua_pg_id = pg_id;
 +
 + list_add_tail(lba_map_mem-lba_map_mem_list,
 +   lba_map-lba_map_mem_list);
 + return 0;
 +}

Ditto here..

 +
 +void
 +core_alua_free_lba_map(struct list_head *lba_list)
 +{
 + struct t10_alua_lba_map *lba_map, *lba_map_tmp;
 + struct t10_alua_lba_map_member *lba_map_mem, *lba_map_mem_tmp;
 +
 + list_for_each_entry_safe(lba_map, lba_map_tmp, lba_list,
 +  lba_map_list) {
 + list_for_each_entry_safe(lba_map_mem, lba_map_mem_tmp,
 +  lba_map-lba_map_mem_list,
 +  lba_map_mem_list) {
 + list_del(lba_map_mem-lba_map_mem_list);
 + kmem_cache_free(t10_alua_lba_map_mem_cache,
 + lba_map_mem);
 + }
 + list_del(lba_map-lba_map_list);
 + kmem_cache_free(t10_alua_lba_map_cache, lba_map);
 + }
 +}

And here..

 +
 +void
 +core_alua_set_lba_map(struct se_device *dev, struct list_head *lba_map_list,
 +   int segment_size, int segment_mult)
 +{
 + struct list_head old_lba_map_list;
 + struct t10_alua_tg_pt_gp *tg_pt_gp;
 + int activate = 0, supported;
 +
 + INIT_LIST_HEAD(old_lba_map_list);
 + spin_lock(dev-t10_alua.lba_map_lock);
 + dev-t10_alua.lba_map_segment_size = segment_size;
 + dev-t10_alua.lba_map_segment_multiplier = segment_mult;
 + list_splice_init(dev-t10_alua.lba_map_list, old_lba_map_list);
 + if (lba_map_list) {
 + list_splice_init(lba_map_list, dev-t10_alua.lba_map_list);
 + activate = 1;
 + }
 + spin_unlock(dev-t10_alua.lba_map_lock);
 + spin_lock(dev-t10_alua.tg_pt_gps_lock);
 + list_for_each_entry(tg_pt_gp, dev-t10_alua.tg_pt_gps_list,
 + tg_pt_gp_list) {
 +
 + if (!tg_pt_gp-tg_pt_gp_valid_id)
 + continue;
 + supported = tg_pt_gp-tg_pt_gp_alua_supported_states;
 + if (activate)
 + supported |= ALUA_LBD_SUP;
 + else
 + supported = ~ALUA_LBD_SUP;
 + tg_pt_gp-tg_pt_gp_alua_supported_states = supported;
 + }
 + spin_unlock(dev-t10_alua.tg_pt_gps_lock);
 + core_alua_free_lba_map(old_lba_map_list);
 +}
 +
  struct t10_alua_lu_gp *
  core_alua_allocate_lu_gp(const char *name, int def_group)
  {
 diff --git a/drivers/target/target_core_alua.h 
 

RE: [PATCH][SCSI] megaraid_sas: Fix synchronization problem between sysPD IO path and AEN path

2013-10-16 Thread Saxena, Sumit


-Original Message-
From: James Bottomley [mailto:jbottom...@parallels.com]
Sent: Thursday, October 17, 2013 3:15 AM
To: Saxena, Sumit
Cc: linux-scsi@vger.kernel.org; Desai, Kashyap; aradf...@gmail.com
Subject: Re: [PATCH][SCSI] megaraid_sas: Fix synchronization problem
between sysPD IO path and AEN path

On Wed, 2013-10-16 at 17:04 +0530, sumit.sax...@lsi.com wrote:
 There is syncronization problem between sysPD IO path and AEN path.
 Driver maintains instance-pd_list[] array, which will get updated(by
 calling function megasas_get_pd_list[]), whenever any of below events
 occurs-

 MR_EVT_PD_INSERTED
 MR_EVT_PD_REMOVED
 MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED
 MR_EVT_FOREIGN_CFG_IMPORTED

 At same time running sysPD IO will be accessing the same array
 instance-pd_list[], which is getting updated in AEN path, because of
this IO may not get correct PD info from instance-pd_list[] array.

 Signed-off-by: Adam Radford adam.radf...@lsi.com
 Signed-off-by: Sumit Saxena sumit.sax...@lsi.com

Explain the signoff chain: is this a joinly authored patch?

Yes, it's jointly authored patch. Originally, this patch is authored by Adam 
Radford, and then modified by me(Sumit Saxena).


James



--
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/11] target_core_alua: Store supported ALUA states

2013-10-16 Thread Hannes Reinecke
On 10/16/2013 11:19 PM, Nicholas A. Bellinger wrote:
 On Wed, 2013-10-16 at 09:20 +0200, Hannes Reinecke wrote:
 The supported ALUA states might be different for individual
 devices, so store it in a separate field.

 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
  drivers/target/target_core_alua.c | 14 --
  drivers/target/target_core_alua.h | 11 +++
  include/target/target_core_base.h |  1 +
  3 files changed, 20 insertions(+), 6 deletions(-)

 diff --git a/drivers/target/target_core_alua.c 
 b/drivers/target/target_core_alua.c
 index 8297d37..255e83c 100644
 --- a/drivers/target/target_core_alua.c
 +++ b/drivers/target/target_core_alua.c
 @@ -117,12 +117,7 @@ target_emulate_report_target_port_groups(struct se_cmd 
 *cmd)
  /*
   * Set supported ASYMMETRIC ACCESS State bits
   */
 -buf[off] = 0x80; /* T_SUP */
 -buf[off] |= 0x40; /* O_SUP */
 -buf[off] |= 0x8; /* U_SUP */
 -buf[off] |= 0x4; /* S_SUP */
 -buf[off] |= 0x2; /* AN_SUP */
 -buf[off++] |= 0x1; /* AO_SUP */
 +buf[off++] |= tg_pt_gp-tg_pt_gp_alua_supported_states;
  /*
   * TARGET PORT GROUP
   */
 @@ -1367,6 +1362,13 @@ struct t10_alua_tg_pt_gp 
 *core_alua_allocate_tg_pt_gp(struct se_device *dev,
  tg_pt_gp-tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
  tg_pt_gp-tg_pt_gp_implicit_trans_secs = 
 ALUA_DEFAULT_IMPLICIT_TRANS_SECS;
  
 +/*
 + * Enable all supported states
 + */
 +tg_pt_gp-tg_pt_gp_alua_supported_states =
 +ALUA_T_SUP | ALUA_O_SUP | \
 +ALUA_U_SUP | ALUA_S_SUP | ALUA_AN_SUP | ALUA_AO_SUP;
 +
  if (def_group) {
  spin_lock(dev-t10_alua.tg_pt_gps_lock);
  tg_pt_gp-tg_pt_gp_id =
 diff --git a/drivers/target/target_core_alua.h 
 b/drivers/target/target_core_alua.h
 index 74cf0c0..e826a65 100644
 --- a/drivers/target/target_core_alua.h
 +++ b/drivers/target/target_core_alua.h
 @@ -23,6 +23,17 @@
  #define ALUA_ACCESS_STATE_TRANSITION0xf
  
  /*
 + * from spc4r36j section 6.37 Table 306
 + */
 +#define ALUA_T_SUP  0x80
 +#define ALUA_O_SUP  0x40
 +#define ALUA_LBD_SUP0x10
 +#define ALUA_U_SUP  0x08
 +#define ALUA_S_SUP  0x04
 +#define ALUA_AN_SUP 0x02
 +#define ALUA_AO_SUP 0x01
 +
 +/*
 
 How about making these the supported bits, TPGS mode, and ALUA access
 state definitions common between target_core_alua.c and
 scsi_dh_alua.c..?
 
Sure. Good idea.

Cheers,

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