aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/target/target_core_alua.c82
-rw-r--r--drivers/target/target_core_alua.h10
-rw-r--r--drivers/target/target_core_configfs.c21
-rw-r--r--include/target/target_core_base.h1
4 files changed, 102 insertions, 12 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index be7251ee8b3a..e624b836469c 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -66,18 +66,24 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
66 struct t10_alua_tg_pt_gp *tg_pt_gp; 66 struct t10_alua_tg_pt_gp *tg_pt_gp;
67 struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; 67 struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
68 unsigned char *buf; 68 unsigned char *buf;
69 u32 rd_len = 0, off = 4; /* Skip over RESERVED area to first 69 u32 rd_len = 0, off;
70 Target port group descriptor */ 70 int ext_hdr = (cmd->t_task_cdb[1] & 0x20);
71 /* 71 /*
72 * Need at least 4 bytes of response data or else we can't 72 * Skip over RESERVED area to first Target port group descriptor
73 * even fit the return data length. 73 * depending on the PARAMETER DATA FORMAT type..
74 */ 74 */
75 if (cmd->data_length < 4) { 75 if (ext_hdr != 0)
76 pr_warn("REPORT TARGET PORT GROUPS allocation length %u" 76 off = 8;
77 " too small\n", cmd->data_length); 77 else
78 off = 4;
79
80 if (cmd->data_length < off) {
81 pr_warn("REPORT TARGET PORT GROUPS allocation length %u too"
82 " small for %s header\n", cmd->data_length,
83 (ext_hdr) ? "extended" : "normal");
84 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
78 return -EINVAL; 85 return -EINVAL;
79 } 86 }
80
81 buf = transport_kmap_data_sg(cmd); 87 buf = transport_kmap_data_sg(cmd);
82 88
83 spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); 89 spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
@@ -158,11 +164,31 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
158 /* 164 /*
159 * Set the RETURN DATA LENGTH set in the header of the DataIN Payload 165 * Set the RETURN DATA LENGTH set in the header of the DataIN Payload
160 */ 166 */
161 buf[0] = ((rd_len >> 24) & 0xff); 167 put_unaligned_be32(rd_len, &buf[0]);
162 buf[1] = ((rd_len >> 16) & 0xff);
163 buf[2] = ((rd_len >> 8) & 0xff);
164 buf[3] = (rd_len & 0xff);
165 168
169 /*
170 * Fill in the Extended header parameter data format if requested
171 */
172 if (ext_hdr != 0) {
173 buf[4] = 0x10;
174 /*
175 * Set the implict transition time (in seconds) for the application
176 * client to use as a base for it's transition timeout value.
177 *
178 * Use the current tg_pt_gp_mem -> tg_pt_gp membership from the LUN
179 * this CDB was received upon to determine this value individually
180 * for ALUA target port group.
181 */
182 port = cmd->se_lun->lun_sep;
183 tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
184 if (tg_pt_gp_mem) {
185 spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
186 tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
187 if (tg_pt_gp)
188 buf[5] = tg_pt_gp->tg_pt_gp_implict_trans_secs;
189 spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
190 }
191 }
166 transport_kunmap_data_sg(cmd); 192 transport_kunmap_data_sg(cmd);
167 193
168 target_complete_cmd(cmd, GOOD); 194 target_complete_cmd(cmd, GOOD);
@@ -1355,6 +1381,7 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
1355 */ 1381 */
1356 tg_pt_gp->tg_pt_gp_nonop_delay_msecs = ALUA_DEFAULT_NONOP_DELAY_MSECS; 1382 tg_pt_gp->tg_pt_gp_nonop_delay_msecs = ALUA_DEFAULT_NONOP_DELAY_MSECS;
1357 tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS; 1383 tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
1384 tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS;
1358 1385
1359 if (def_group) { 1386 if (def_group) {
1360 spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); 1387 spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
@@ -1851,6 +1878,37 @@ ssize_t core_alua_store_trans_delay_msecs(
1851 return count; 1878 return count;
1852} 1879}
1853 1880
1881ssize_t core_alua_show_implict_trans_secs(
1882 struct t10_alua_tg_pt_gp *tg_pt_gp,
1883 char *page)
1884{
1885 return sprintf(page, "%d\n", tg_pt_gp->tg_pt_gp_implict_trans_secs);
1886}
1887
1888ssize_t core_alua_store_implict_trans_secs(
1889 struct t10_alua_tg_pt_gp *tg_pt_gp,
1890 const char *page,
1891 size_t count)
1892{
1893 unsigned long tmp;
1894 int ret;
1895
1896 ret = strict_strtoul(page, 0, &tmp);
1897 if (ret < 0) {
1898 pr_err("Unable to extract implict_trans_secs\n");
1899 return -EINVAL;
1900 }
1901 if (tmp > ALUA_MAX_IMPLICT_TRANS_SECS) {
1902 pr_err("Passed implict_trans_secs: %lu, exceeds"
1903 " ALUA_MAX_IMPLICT_TRANS_SECS: %d\n", tmp,
1904 ALUA_MAX_IMPLICT_TRANS_SECS);
1905 return -EINVAL;
1906 }
1907 tg_pt_gp->tg_pt_gp_implict_trans_secs = (int)tmp;
1908
1909 return count;
1910}
1911
1854ssize_t core_alua_show_preferred_bit( 1912ssize_t core_alua_show_preferred_bit(
1855 struct t10_alua_tg_pt_gp *tg_pt_gp, 1913 struct t10_alua_tg_pt_gp *tg_pt_gp,
1856 char *page) 1914 char *page)
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index e26454324752..f920c170d47b 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -52,6 +52,12 @@
52#define ALUA_DEFAULT_TRANS_DELAY_MSECS 0 52#define ALUA_DEFAULT_TRANS_DELAY_MSECS 0
53#define ALUA_MAX_TRANS_DELAY_MSECS 30000 /* 30 seconds */ 53#define ALUA_MAX_TRANS_DELAY_MSECS 30000 /* 30 seconds */
54/* 54/*
55 * Used for the recommended application client implict transition timeout
56 * in seconds, returned by the REPORT_TARGET_PORT_GROUPS w/ extended header.
57 */
58#define ALUA_DEFAULT_IMPLICT_TRANS_SECS 0
59#define ALUA_MAX_IMPLICT_TRANS_SECS 255
60/*
55 * Used by core_alua_update_tpg_primary_metadata() and 61 * Used by core_alua_update_tpg_primary_metadata() and
56 * core_alua_update_tpg_secondary_metadata() 62 * core_alua_update_tpg_secondary_metadata()
57 */ 63 */
@@ -107,6 +113,10 @@ extern ssize_t core_alua_show_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
107 char *); 113 char *);
108extern ssize_t core_alua_store_trans_delay_msecs(struct t10_alua_tg_pt_gp *, 114extern ssize_t core_alua_store_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
109 const char *, size_t); 115 const char *, size_t);
116extern ssize_t core_alua_show_implict_trans_secs(struct t10_alua_tg_pt_gp *,
117 char *);
118extern ssize_t core_alua_store_implict_trans_secs(struct t10_alua_tg_pt_gp *,
119 const char *, size_t);
110extern ssize_t core_alua_show_preferred_bit(struct t10_alua_tg_pt_gp *, 120extern ssize_t core_alua_show_preferred_bit(struct t10_alua_tg_pt_gp *,
111 char *); 121 char *);
112extern ssize_t core_alua_store_preferred_bit(struct t10_alua_tg_pt_gp *, 122extern ssize_t core_alua_store_preferred_bit(struct t10_alua_tg_pt_gp *,
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 931521cc4e4f..801efa892046 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -2447,6 +2447,26 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_trans_delay_msecs(
2447SE_DEV_ALUA_TG_PT_ATTR(trans_delay_msecs, S_IRUGO | S_IWUSR); 2447SE_DEV_ALUA_TG_PT_ATTR(trans_delay_msecs, S_IRUGO | S_IWUSR);
2448 2448
2449/* 2449/*
2450 * implict_trans_secs
2451 */
2452static ssize_t target_core_alua_tg_pt_gp_show_attr_implict_trans_secs(
2453 struct t10_alua_tg_pt_gp *tg_pt_gp,
2454 char *page)
2455{
2456 return core_alua_show_implict_trans_secs(tg_pt_gp, page);
2457}
2458
2459static ssize_t target_core_alua_tg_pt_gp_store_attr_implict_trans_secs(
2460 struct t10_alua_tg_pt_gp *tg_pt_gp,
2461 const char *page,
2462 size_t count)
2463{
2464 return core_alua_store_implict_trans_secs(tg_pt_gp, page, count);
2465}
2466
2467SE_DEV_ALUA_TG_PT_ATTR(implict_trans_secs, S_IRUGO | S_IWUSR);
2468
2469/*
2450 * preferred 2470 * preferred
2451 */ 2471 */
2452 2472
@@ -2570,6 +2590,7 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
2570 &target_core_alua_tg_pt_gp_alua_write_metadata.attr, 2590 &target_core_alua_tg_pt_gp_alua_write_metadata.attr,
2571 &target_core_alua_tg_pt_gp_nonop_delay_msecs.attr, 2591 &target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
2572 &target_core_alua_tg_pt_gp_trans_delay_msecs.attr, 2592 &target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
2593 &target_core_alua_tg_pt_gp_implict_trans_secs.attr,
2573 &target_core_alua_tg_pt_gp_preferred.attr, 2594 &target_core_alua_tg_pt_gp_preferred.attr,
2574 &target_core_alua_tg_pt_gp_tg_pt_gp_id.attr, 2595 &target_core_alua_tg_pt_gp_tg_pt_gp_id.attr,
2575 &target_core_alua_tg_pt_gp_members.attr, 2596 &target_core_alua_tg_pt_gp_members.attr,
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 1fe9111f4dc1..dc35d8660aa6 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -330,6 +330,7 @@ struct t10_alua_tg_pt_gp {
330 int tg_pt_gp_alua_access_type; 330 int tg_pt_gp_alua_access_type;
331 int tg_pt_gp_nonop_delay_msecs; 331 int tg_pt_gp_nonop_delay_msecs;
332 int tg_pt_gp_trans_delay_msecs; 332 int tg_pt_gp_trans_delay_msecs;
333 int tg_pt_gp_implict_trans_secs;
333 int tg_pt_gp_pref; 334 int tg_pt_gp_pref;
334 int tg_pt_gp_write_metadata; 335 int tg_pt_gp_write_metadata;
335 /* Used by struct t10_alua_tg_pt_gp->tg_pt_gp_md_buf_len */ 336 /* Used by struct t10_alua_tg_pt_gp->tg_pt_gp_md_buf_len */