diff options
Diffstat (limited to 'drivers/target/target_core_alua.c')
-rw-r--r-- | drivers/target/target_core_alua.c | 346 |
1 files changed, 144 insertions, 202 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 9a5f9a7aecd2..85140f7dde1e 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -3,8 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This file contains SPC-3 compliant asymmetric logical unit assigntment (ALUA) | 4 | * This file contains SPC-3 compliant asymmetric logical unit assigntment (ALUA) |
5 | * | 5 | * |
6 | * Copyright (c) 2009-2010 Rising Tide Systems | 6 | * (c) Copyright 2009-2012 RisingTide Systems LLC. |
7 | * Copyright (c) 2009-2010 Linux-iSCSI.org | ||
8 | * | 7 | * |
9 | * Nicholas A. Bellinger <nab@kernel.org> | 8 | * Nicholas A. Bellinger <nab@kernel.org> |
10 | * | 9 | * |
@@ -41,7 +40,7 @@ | |||
41 | #include "target_core_alua.h" | 40 | #include "target_core_alua.h" |
42 | #include "target_core_ua.h" | 41 | #include "target_core_ua.h" |
43 | 42 | ||
44 | static int core_alua_check_transition(int state, int *primary); | 43 | static sense_reason_t core_alua_check_transition(int state, int *primary); |
45 | static int core_alua_set_tg_pt_secondary_state( | 44 | static int core_alua_set_tg_pt_secondary_state( |
46 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, | 45 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, |
47 | struct se_port *port, int explict, int offline); | 46 | struct se_port *port, int explict, int offline); |
@@ -59,15 +58,17 @@ struct t10_alua_lu_gp *default_lu_gp; | |||
59 | * | 58 | * |
60 | * See spc4r17 section 6.27 | 59 | * See spc4r17 section 6.27 |
61 | */ | 60 | */ |
62 | int target_emulate_report_target_port_groups(struct se_cmd *cmd) | 61 | sense_reason_t |
62 | target_emulate_report_target_port_groups(struct se_cmd *cmd) | ||
63 | { | 63 | { |
64 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | 64 | struct se_device *dev = cmd->se_dev; |
65 | struct se_port *port; | 65 | struct se_port *port; |
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; | 69 | u32 rd_len = 0, off; |
70 | int ext_hdr = (cmd->t_task_cdb[1] & 0x20); | 70 | int ext_hdr = (cmd->t_task_cdb[1] & 0x20); |
71 | |||
71 | /* | 72 | /* |
72 | * Skip over RESERVED area to first Target port group descriptor | 73 | * Skip over RESERVED area to first Target port group descriptor |
73 | * depending on the PARAMETER DATA FORMAT type.. | 74 | * depending on the PARAMETER DATA FORMAT type.. |
@@ -81,13 +82,14 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
81 | pr_warn("REPORT TARGET PORT GROUPS allocation length %u too" | 82 | pr_warn("REPORT TARGET PORT GROUPS allocation length %u too" |
82 | " small for %s header\n", cmd->data_length, | 83 | " small for %s header\n", cmd->data_length, |
83 | (ext_hdr) ? "extended" : "normal"); | 84 | (ext_hdr) ? "extended" : "normal"); |
84 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | 85 | return TCM_INVALID_CDB_FIELD; |
85 | return -EINVAL; | ||
86 | } | 86 | } |
87 | buf = transport_kmap_data_sg(cmd); | 87 | buf = transport_kmap_data_sg(cmd); |
88 | if (!buf) | ||
89 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
88 | 90 | ||
89 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 91 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
90 | list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list, | 92 | list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list, |
91 | tg_pt_gp_list) { | 93 | tg_pt_gp_list) { |
92 | /* | 94 | /* |
93 | * Check if the Target port group and Target port descriptor list | 95 | * Check if the Target port group and Target port descriptor list |
@@ -160,7 +162,7 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
160 | } | 162 | } |
161 | spin_unlock(&tg_pt_gp->tg_pt_gp_lock); | 163 | spin_unlock(&tg_pt_gp->tg_pt_gp_lock); |
162 | } | 164 | } |
163 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 165 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
164 | /* | 166 | /* |
165 | * Set the RETURN DATA LENGTH set in the header of the DataIN Payload | 167 | * Set the RETURN DATA LENGTH set in the header of the DataIN Payload |
166 | */ | 168 | */ |
@@ -200,32 +202,33 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd) | |||
200 | * | 202 | * |
201 | * See spc4r17 section 6.35 | 203 | * See spc4r17 section 6.35 |
202 | */ | 204 | */ |
203 | int target_emulate_set_target_port_groups(struct se_cmd *cmd) | 205 | sense_reason_t |
206 | target_emulate_set_target_port_groups(struct se_cmd *cmd) | ||
204 | { | 207 | { |
205 | struct se_device *dev = cmd->se_dev; | 208 | struct se_device *dev = cmd->se_dev; |
206 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
207 | struct se_port *port, *l_port = cmd->se_lun->lun_sep; | 209 | struct se_port *port, *l_port = cmd->se_lun->lun_sep; |
208 | struct se_node_acl *nacl = cmd->se_sess->se_node_acl; | 210 | struct se_node_acl *nacl = cmd->se_sess->se_node_acl; |
209 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *l_tg_pt_gp; | 211 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *l_tg_pt_gp; |
210 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem; | 212 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *l_tg_pt_gp_mem; |
211 | unsigned char *buf; | 213 | unsigned char *buf; |
212 | unsigned char *ptr; | 214 | unsigned char *ptr; |
215 | sense_reason_t rc; | ||
213 | u32 len = 4; /* Skip over RESERVED area in header */ | 216 | u32 len = 4; /* Skip over RESERVED area in header */ |
214 | int alua_access_state, primary = 0, rc; | 217 | int alua_access_state, primary = 0; |
215 | u16 tg_pt_id, rtpi; | 218 | u16 tg_pt_id, rtpi; |
216 | 219 | ||
217 | if (!l_port) { | 220 | if (!l_port) |
218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 221 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
219 | return -EINVAL; | 222 | |
220 | } | ||
221 | if (cmd->data_length < 4) { | 223 | if (cmd->data_length < 4) { |
222 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" | 224 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" |
223 | " small\n", cmd->data_length); | 225 | " small\n", cmd->data_length); |
224 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 226 | return TCM_INVALID_PARAMETER_LIST; |
225 | return -EINVAL; | ||
226 | } | 227 | } |
227 | 228 | ||
228 | buf = transport_kmap_data_sg(cmd); | 229 | buf = transport_kmap_data_sg(cmd); |
230 | if (!buf) | ||
231 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
229 | 232 | ||
230 | /* | 233 | /* |
231 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed | 234 | * Determine if explict ALUA via SET_TARGET_PORT_GROUPS is allowed |
@@ -234,8 +237,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
234 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; | 237 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; |
235 | if (!l_tg_pt_gp_mem) { | 238 | if (!l_tg_pt_gp_mem) { |
236 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); | 239 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); |
237 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 240 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
238 | rc = -EINVAL; | ||
239 | goto out; | 241 | goto out; |
240 | } | 242 | } |
241 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 243 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -243,24 +245,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
243 | if (!l_tg_pt_gp) { | 245 | if (!l_tg_pt_gp) { |
244 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 246 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
245 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); | 247 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); |
246 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 248 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
247 | rc = -EINVAL; | ||
248 | goto out; | 249 | goto out; |
249 | } | 250 | } |
250 | rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); | ||
251 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 251 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
252 | 252 | ||
253 | if (!rc) { | 253 | if (!(l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA)) { |
254 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" | 254 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" |
255 | " while TPGS_EXPLICT_ALUA is disabled\n"); | 255 | " while TPGS_EXPLICT_ALUA is disabled\n"); |
256 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 256 | rc = TCM_UNSUPPORTED_SCSI_OPCODE; |
257 | rc = -EINVAL; | ||
258 | goto out; | 257 | goto out; |
259 | } | 258 | } |
260 | 259 | ||
261 | ptr = &buf[4]; /* Skip over RESERVED area in header */ | 260 | ptr = &buf[4]; /* Skip over RESERVED area in header */ |
262 | 261 | ||
263 | while (len < cmd->data_length) { | 262 | while (len < cmd->data_length) { |
263 | bool found = false; | ||
264 | alua_access_state = (ptr[0] & 0x0f); | 264 | alua_access_state = (ptr[0] & 0x0f); |
265 | /* | 265 | /* |
266 | * Check the received ALUA access state, and determine if | 266 | * Check the received ALUA access state, and determine if |
@@ -268,7 +268,7 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
268 | * access state. | 268 | * access state. |
269 | */ | 269 | */ |
270 | rc = core_alua_check_transition(alua_access_state, &primary); | 270 | rc = core_alua_check_transition(alua_access_state, &primary); |
271 | if (rc != 0) { | 271 | if (rc) { |
272 | /* | 272 | /* |
273 | * If the SET TARGET PORT GROUPS attempts to establish | 273 | * If the SET TARGET PORT GROUPS attempts to establish |
274 | * an invalid combination of target port asymmetric | 274 | * an invalid combination of target port asymmetric |
@@ -279,11 +279,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
279 | * REQUEST, and the additional sense code set to INVALID | 279 | * REQUEST, and the additional sense code set to INVALID |
280 | * FIELD IN PARAMETER LIST. | 280 | * FIELD IN PARAMETER LIST. |
281 | */ | 281 | */ |
282 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
283 | rc = -EINVAL; | ||
284 | goto out; | 282 | goto out; |
285 | } | 283 | } |
286 | rc = -1; | 284 | |
287 | /* | 285 | /* |
288 | * If the ASYMMETRIC ACCESS STATE field (see table 267) | 286 | * If the ASYMMETRIC ACCESS STATE field (see table 267) |
289 | * specifies a primary target port asymmetric access state, | 287 | * specifies a primary target port asymmetric access state, |
@@ -303,9 +301,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
303 | * Locate the matching target port group ID from | 301 | * Locate the matching target port group ID from |
304 | * the global tg_pt_gp list | 302 | * the global tg_pt_gp list |
305 | */ | 303 | */ |
306 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 304 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
307 | list_for_each_entry(tg_pt_gp, | 305 | list_for_each_entry(tg_pt_gp, |
308 | &su_dev->t10_alua.tg_pt_gps_list, | 306 | &dev->t10_alua.tg_pt_gps_list, |
309 | tg_pt_gp_list) { | 307 | tg_pt_gp_list) { |
310 | if (!tg_pt_gp->tg_pt_gp_valid_id) | 308 | if (!tg_pt_gp->tg_pt_gp_valid_id) |
311 | continue; | 309 | continue; |
@@ -315,27 +313,20 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
315 | 313 | ||
316 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 314 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
317 | smp_mb__after_atomic_inc(); | 315 | smp_mb__after_atomic_inc(); |
318 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | ||
319 | 316 | ||
320 | rc = core_alua_do_port_transition(tg_pt_gp, | 317 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
318 | |||
319 | if (!core_alua_do_port_transition(tg_pt_gp, | ||
321 | dev, l_port, nacl, | 320 | dev, l_port, nacl, |
322 | alua_access_state, 1); | 321 | alua_access_state, 1)) |
322 | found = true; | ||
323 | 323 | ||
324 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 324 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
325 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 325 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
326 | smp_mb__after_atomic_dec(); | 326 | smp_mb__after_atomic_dec(); |
327 | break; | 327 | break; |
328 | } | 328 | } |
329 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 329 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
330 | /* | ||
331 | * If not matching target port group ID can be located | ||
332 | * throw an exception with ASCQ: INVALID_PARAMETER_LIST | ||
333 | */ | ||
334 | if (rc != 0) { | ||
335 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
336 | rc = -EINVAL; | ||
337 | goto out; | ||
338 | } | ||
339 | } else { | 330 | } else { |
340 | /* | 331 | /* |
341 | * Extact the RELATIVE TARGET PORT IDENTIFIER to identify | 332 | * Extact the RELATIVE TARGET PORT IDENTIFIER to identify |
@@ -354,25 +345,22 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
354 | continue; | 345 | continue; |
355 | 346 | ||
356 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 347 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
348 | |||
357 | spin_unlock(&dev->se_port_lock); | 349 | spin_unlock(&dev->se_port_lock); |
358 | 350 | ||
359 | rc = core_alua_set_tg_pt_secondary_state( | 351 | if (!core_alua_set_tg_pt_secondary_state( |
360 | tg_pt_gp_mem, port, 1, 1); | 352 | tg_pt_gp_mem, port, 1, 1)) |
353 | found = true; | ||
361 | 354 | ||
362 | spin_lock(&dev->se_port_lock); | 355 | spin_lock(&dev->se_port_lock); |
363 | break; | 356 | break; |
364 | } | 357 | } |
365 | spin_unlock(&dev->se_port_lock); | 358 | spin_unlock(&dev->se_port_lock); |
366 | /* | 359 | } |
367 | * If not matching relative target port identifier can | 360 | |
368 | * be located, throw an exception with ASCQ: | 361 | if (!found) { |
369 | * INVALID_PARAMETER_LIST | 362 | rc = TCM_INVALID_PARAMETER_LIST; |
370 | */ | 363 | goto out; |
371 | if (rc != 0) { | ||
372 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
373 | rc = -EINVAL; | ||
374 | goto out; | ||
375 | } | ||
376 | } | 364 | } |
377 | 365 | ||
378 | ptr += 4; | 366 | ptr += 4; |
@@ -523,40 +511,27 @@ static inline int core_alua_state_transition( | |||
523 | } | 511 | } |
524 | 512 | ||
525 | /* | 513 | /* |
526 | * Used for alua_type SPC_ALUA_PASSTHROUGH and SPC2_ALUA_DISABLED | ||
527 | * in transport_cmd_sequencer(). This function is assigned to | ||
528 | * struct t10_alua *->state_check() in core_setup_alua() | ||
529 | */ | ||
530 | static int core_alua_state_check_nop( | ||
531 | struct se_cmd *cmd, | ||
532 | unsigned char *cdb, | ||
533 | u8 *alua_ascq) | ||
534 | { | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | /* | ||
539 | * Used for alua_type SPC3_ALUA_EMULATED in transport_cmd_sequencer(). | ||
540 | * This function is assigned to struct t10_alua *->state_check() in | ||
541 | * core_setup_alua() | ||
542 | * | ||
543 | * Also, this function can return three different return codes to | ||
544 | * signal transport_generic_cmd_sequencer() | ||
545 | * | ||
546 | * return 1: Is used to signal LUN not accecsable, and check condition/not ready | 514 | * return 1: Is used to signal LUN not accecsable, and check condition/not ready |
547 | * return 0: Used to signal success | 515 | * return 0: Used to signal success |
548 | * reutrn -1: Used to signal failure, and invalid cdb field | 516 | * reutrn -1: Used to signal failure, and invalid cdb field |
549 | */ | 517 | */ |
550 | static int core_alua_state_check( | 518 | sense_reason_t |
551 | struct se_cmd *cmd, | 519 | target_alua_state_check(struct se_cmd *cmd) |
552 | unsigned char *cdb, | ||
553 | u8 *alua_ascq) | ||
554 | { | 520 | { |
521 | struct se_device *dev = cmd->se_dev; | ||
522 | unsigned char *cdb = cmd->t_task_cdb; | ||
555 | struct se_lun *lun = cmd->se_lun; | 523 | struct se_lun *lun = cmd->se_lun; |
556 | struct se_port *port = lun->lun_sep; | 524 | struct se_port *port = lun->lun_sep; |
557 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 525 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
558 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 526 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
559 | int out_alua_state, nonop_delay_msecs; | 527 | int out_alua_state, nonop_delay_msecs; |
528 | u8 alua_ascq; | ||
529 | int ret; | ||
530 | |||
531 | if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) | ||
532 | return 0; | ||
533 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) | ||
534 | return 0; | ||
560 | 535 | ||
561 | if (!port) | 536 | if (!port) |
562 | return 0; | 537 | return 0; |
@@ -565,11 +540,11 @@ static int core_alua_state_check( | |||
565 | * access state: OFFLINE | 540 | * access state: OFFLINE |
566 | */ | 541 | */ |
567 | if (atomic_read(&port->sep_tg_pt_secondary_offline)) { | 542 | if (atomic_read(&port->sep_tg_pt_secondary_offline)) { |
568 | *alua_ascq = ASCQ_04H_ALUA_OFFLINE; | ||
569 | pr_debug("ALUA: Got secondary offline status for local" | 543 | pr_debug("ALUA: Got secondary offline status for local" |
570 | " target port\n"); | 544 | " target port\n"); |
571 | *alua_ascq = ASCQ_04H_ALUA_OFFLINE; | 545 | alua_ascq = ASCQ_04H_ALUA_OFFLINE; |
572 | return 1; | 546 | ret = 1; |
547 | goto out; | ||
573 | } | 548 | } |
574 | /* | 549 | /* |
575 | * Second, obtain the struct t10_alua_tg_pt_gp_member pointer to the | 550 | * Second, obtain the struct t10_alua_tg_pt_gp_member pointer to the |
@@ -594,14 +569,18 @@ static int core_alua_state_check( | |||
594 | 569 | ||
595 | switch (out_alua_state) { | 570 | switch (out_alua_state) { |
596 | case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED: | 571 | case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED: |
597 | return core_alua_state_nonoptimized(cmd, cdb, | 572 | ret = core_alua_state_nonoptimized(cmd, cdb, |
598 | nonop_delay_msecs, alua_ascq); | 573 | nonop_delay_msecs, &alua_ascq); |
574 | break; | ||
599 | case ALUA_ACCESS_STATE_STANDBY: | 575 | case ALUA_ACCESS_STATE_STANDBY: |
600 | return core_alua_state_standby(cmd, cdb, alua_ascq); | 576 | ret = core_alua_state_standby(cmd, cdb, &alua_ascq); |
577 | break; | ||
601 | case ALUA_ACCESS_STATE_UNAVAILABLE: | 578 | case ALUA_ACCESS_STATE_UNAVAILABLE: |
602 | return core_alua_state_unavailable(cmd, cdb, alua_ascq); | 579 | ret = core_alua_state_unavailable(cmd, cdb, &alua_ascq); |
580 | break; | ||
603 | case ALUA_ACCESS_STATE_TRANSITION: | 581 | case ALUA_ACCESS_STATE_TRANSITION: |
604 | return core_alua_state_transition(cmd, cdb, alua_ascq); | 582 | ret = core_alua_state_transition(cmd, cdb, &alua_ascq); |
583 | break; | ||
605 | /* | 584 | /* |
606 | * OFFLINE is a secondary ALUA target port group access state, that is | 585 | * OFFLINE is a secondary ALUA target port group access state, that is |
607 | * handled above with struct se_port->sep_tg_pt_secondary_offline=1 | 586 | * handled above with struct se_port->sep_tg_pt_secondary_offline=1 |
@@ -610,7 +589,24 @@ static int core_alua_state_check( | |||
610 | default: | 589 | default: |
611 | pr_err("Unknown ALUA access state: 0x%02x\n", | 590 | pr_err("Unknown ALUA access state: 0x%02x\n", |
612 | out_alua_state); | 591 | out_alua_state); |
613 | return -EINVAL; | 592 | return TCM_INVALID_CDB_FIELD; |
593 | } | ||
594 | |||
595 | out: | ||
596 | if (ret > 0) { | ||
597 | /* | ||
598 | * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; | ||
599 | * The ALUA additional sense code qualifier (ASCQ) is determined | ||
600 | * by the ALUA primary or secondary access state.. | ||
601 | */ | ||
602 | pr_debug("[%s]: ALUA TG Port not available, " | ||
603 | "SenseKey: NOT_READY, ASC/ASCQ: " | ||
604 | "0x04/0x%02x\n", | ||
605 | cmd->se_tfo->get_fabric_name(), alua_ascq); | ||
606 | |||
607 | cmd->scsi_asc = 0x04; | ||
608 | cmd->scsi_ascq = alua_ascq; | ||
609 | return TCM_CHECK_CONDITION_NOT_READY; | ||
614 | } | 610 | } |
615 | 611 | ||
616 | return 0; | 612 | return 0; |
@@ -619,7 +615,8 @@ static int core_alua_state_check( | |||
619 | /* | 615 | /* |
620 | * Check implict and explict ALUA state change request. | 616 | * Check implict and explict ALUA state change request. |
621 | */ | 617 | */ |
622 | static int core_alua_check_transition(int state, int *primary) | 618 | static sense_reason_t |
619 | core_alua_check_transition(int state, int *primary) | ||
623 | { | 620 | { |
624 | switch (state) { | 621 | switch (state) { |
625 | case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED: | 622 | case ALUA_ACCESS_STATE_ACTIVE_OPTMIZED: |
@@ -641,7 +638,7 @@ static int core_alua_check_transition(int state, int *primary) | |||
641 | break; | 638 | break; |
642 | default: | 639 | default: |
643 | pr_err("Unknown ALUA access state: 0x%02x\n", state); | 640 | pr_err("Unknown ALUA access state: 0x%02x\n", state); |
644 | return -EINVAL; | 641 | return TCM_INVALID_PARAMETER_LIST; |
645 | } | 642 | } |
646 | 643 | ||
647 | return 0; | 644 | return 0; |
@@ -758,8 +755,7 @@ static int core_alua_update_tpg_primary_metadata( | |||
758 | int primary_state, | 755 | int primary_state, |
759 | unsigned char *md_buf) | 756 | unsigned char *md_buf) |
760 | { | 757 | { |
761 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 758 | struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn; |
762 | struct t10_wwn *wwn = &su_dev->t10_wwn; | ||
763 | char path[ALUA_METADATA_PATH_LEN]; | 759 | char path[ALUA_METADATA_PATH_LEN]; |
764 | int len; | 760 | int len; |
765 | 761 | ||
@@ -899,7 +895,6 @@ int core_alua_do_port_transition( | |||
899 | { | 895 | { |
900 | struct se_device *dev; | 896 | struct se_device *dev; |
901 | struct se_port *port; | 897 | struct se_port *port; |
902 | struct se_subsystem_dev *su_dev; | ||
903 | struct se_node_acl *nacl; | 898 | struct se_node_acl *nacl; |
904 | struct t10_alua_lu_gp *lu_gp; | 899 | struct t10_alua_lu_gp *lu_gp; |
905 | struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem; | 900 | struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem; |
@@ -949,14 +944,13 @@ int core_alua_do_port_transition( | |||
949 | lu_gp_mem_list) { | 944 | lu_gp_mem_list) { |
950 | 945 | ||
951 | dev = lu_gp_mem->lu_gp_mem_dev; | 946 | dev = lu_gp_mem->lu_gp_mem_dev; |
952 | su_dev = dev->se_sub_dev; | ||
953 | atomic_inc(&lu_gp_mem->lu_gp_mem_ref_cnt); | 947 | atomic_inc(&lu_gp_mem->lu_gp_mem_ref_cnt); |
954 | smp_mb__after_atomic_inc(); | 948 | smp_mb__after_atomic_inc(); |
955 | spin_unlock(&lu_gp->lu_gp_lock); | 949 | spin_unlock(&lu_gp->lu_gp_lock); |
956 | 950 | ||
957 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 951 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
958 | list_for_each_entry(tg_pt_gp, | 952 | list_for_each_entry(tg_pt_gp, |
959 | &su_dev->t10_alua.tg_pt_gps_list, | 953 | &dev->t10_alua.tg_pt_gps_list, |
960 | tg_pt_gp_list) { | 954 | tg_pt_gp_list) { |
961 | 955 | ||
962 | if (!tg_pt_gp->tg_pt_gp_valid_id) | 956 | if (!tg_pt_gp->tg_pt_gp_valid_id) |
@@ -981,7 +975,7 @@ int core_alua_do_port_transition( | |||
981 | } | 975 | } |
982 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 976 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
983 | smp_mb__after_atomic_inc(); | 977 | smp_mb__after_atomic_inc(); |
984 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 978 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
985 | /* | 979 | /* |
986 | * core_alua_do_transition_tg_pt() will always return | 980 | * core_alua_do_transition_tg_pt() will always return |
987 | * success. | 981 | * success. |
@@ -989,11 +983,11 @@ int core_alua_do_port_transition( | |||
989 | core_alua_do_transition_tg_pt(tg_pt_gp, port, | 983 | core_alua_do_transition_tg_pt(tg_pt_gp, port, |
990 | nacl, md_buf, new_state, explict); | 984 | nacl, md_buf, new_state, explict); |
991 | 985 | ||
992 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 986 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
993 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 987 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
994 | smp_mb__after_atomic_dec(); | 988 | smp_mb__after_atomic_dec(); |
995 | } | 989 | } |
996 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 990 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
997 | 991 | ||
998 | spin_lock(&lu_gp->lu_gp_lock); | 992 | spin_lock(&lu_gp->lu_gp_lock); |
999 | atomic_dec(&lu_gp_mem->lu_gp_mem_ref_cnt); | 993 | atomic_dec(&lu_gp_mem->lu_gp_mem_ref_cnt); |
@@ -1268,14 +1262,9 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) | |||
1268 | 1262 | ||
1269 | void core_alua_free_lu_gp_mem(struct se_device *dev) | 1263 | void core_alua_free_lu_gp_mem(struct se_device *dev) |
1270 | { | 1264 | { |
1271 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | ||
1272 | struct t10_alua *alua = &su_dev->t10_alua; | ||
1273 | struct t10_alua_lu_gp *lu_gp; | 1265 | struct t10_alua_lu_gp *lu_gp; |
1274 | struct t10_alua_lu_gp_member *lu_gp_mem; | 1266 | struct t10_alua_lu_gp_member *lu_gp_mem; |
1275 | 1267 | ||
1276 | if (alua->alua_type != SPC3_ALUA_EMULATED) | ||
1277 | return; | ||
1278 | |||
1279 | lu_gp_mem = dev->dev_alua_lu_gp_mem; | 1268 | lu_gp_mem = dev->dev_alua_lu_gp_mem; |
1280 | if (!lu_gp_mem) | 1269 | if (!lu_gp_mem) |
1281 | return; | 1270 | return; |
@@ -1358,10 +1347,8 @@ void __core_alua_drop_lu_gp_mem( | |||
1358 | spin_unlock(&lu_gp->lu_gp_lock); | 1347 | spin_unlock(&lu_gp->lu_gp_lock); |
1359 | } | 1348 | } |
1360 | 1349 | ||
1361 | struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( | 1350 | struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev, |
1362 | struct se_subsystem_dev *su_dev, | 1351 | const char *name, int def_group) |
1363 | const char *name, | ||
1364 | int def_group) | ||
1365 | { | 1352 | { |
1366 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1353 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1367 | 1354 | ||
@@ -1375,7 +1362,7 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( | |||
1375 | mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex); | 1362 | mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex); |
1376 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); | 1363 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); |
1377 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); | 1364 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); |
1378 | tg_pt_gp->tg_pt_gp_su_dev = su_dev; | 1365 | tg_pt_gp->tg_pt_gp_dev = dev; |
1379 | tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN; | 1366 | tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN; |
1380 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, | 1367 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, |
1381 | ALUA_ACCESS_STATE_ACTIVE_OPTMIZED); | 1368 | ALUA_ACCESS_STATE_ACTIVE_OPTMIZED); |
@@ -1392,14 +1379,14 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp( | |||
1392 | tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS; | 1379 | tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS; |
1393 | 1380 | ||
1394 | if (def_group) { | 1381 | if (def_group) { |
1395 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1382 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1396 | tg_pt_gp->tg_pt_gp_id = | 1383 | tg_pt_gp->tg_pt_gp_id = |
1397 | su_dev->t10_alua.alua_tg_pt_gps_counter++; | 1384 | dev->t10_alua.alua_tg_pt_gps_counter++; |
1398 | tg_pt_gp->tg_pt_gp_valid_id = 1; | 1385 | tg_pt_gp->tg_pt_gp_valid_id = 1; |
1399 | su_dev->t10_alua.alua_tg_pt_gps_count++; | 1386 | dev->t10_alua.alua_tg_pt_gps_count++; |
1400 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, | 1387 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, |
1401 | &su_dev->t10_alua.tg_pt_gps_list); | 1388 | &dev->t10_alua.tg_pt_gps_list); |
1402 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1389 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1403 | } | 1390 | } |
1404 | 1391 | ||
1405 | return tg_pt_gp; | 1392 | return tg_pt_gp; |
@@ -1409,9 +1396,10 @@ int core_alua_set_tg_pt_gp_id( | |||
1409 | struct t10_alua_tg_pt_gp *tg_pt_gp, | 1396 | struct t10_alua_tg_pt_gp *tg_pt_gp, |
1410 | u16 tg_pt_gp_id) | 1397 | u16 tg_pt_gp_id) |
1411 | { | 1398 | { |
1412 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 1399 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
1413 | struct t10_alua_tg_pt_gp *tg_pt_gp_tmp; | 1400 | struct t10_alua_tg_pt_gp *tg_pt_gp_tmp; |
1414 | u16 tg_pt_gp_id_tmp; | 1401 | u16 tg_pt_gp_id_tmp; |
1402 | |||
1415 | /* | 1403 | /* |
1416 | * The tg_pt_gp->tg_pt_gp_id may only be set once.. | 1404 | * The tg_pt_gp->tg_pt_gp_id may only be set once.. |
1417 | */ | 1405 | */ |
@@ -1421,19 +1409,19 @@ int core_alua_set_tg_pt_gp_id( | |||
1421 | return -EINVAL; | 1409 | return -EINVAL; |
1422 | } | 1410 | } |
1423 | 1411 | ||
1424 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1412 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1425 | if (su_dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) { | 1413 | if (dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) { |
1426 | pr_err("Maximum ALUA alua_tg_pt_gps_count:" | 1414 | pr_err("Maximum ALUA alua_tg_pt_gps_count:" |
1427 | " 0x0000ffff reached\n"); | 1415 | " 0x0000ffff reached\n"); |
1428 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1416 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1429 | kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp); | 1417 | kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp); |
1430 | return -ENOSPC; | 1418 | return -ENOSPC; |
1431 | } | 1419 | } |
1432 | again: | 1420 | again: |
1433 | tg_pt_gp_id_tmp = (tg_pt_gp_id != 0) ? tg_pt_gp_id : | 1421 | tg_pt_gp_id_tmp = (tg_pt_gp_id != 0) ? tg_pt_gp_id : |
1434 | su_dev->t10_alua.alua_tg_pt_gps_counter++; | 1422 | dev->t10_alua.alua_tg_pt_gps_counter++; |
1435 | 1423 | ||
1436 | list_for_each_entry(tg_pt_gp_tmp, &su_dev->t10_alua.tg_pt_gps_list, | 1424 | list_for_each_entry(tg_pt_gp_tmp, &dev->t10_alua.tg_pt_gps_list, |
1437 | tg_pt_gp_list) { | 1425 | tg_pt_gp_list) { |
1438 | if (tg_pt_gp_tmp->tg_pt_gp_id == tg_pt_gp_id_tmp) { | 1426 | if (tg_pt_gp_tmp->tg_pt_gp_id == tg_pt_gp_id_tmp) { |
1439 | if (!tg_pt_gp_id) | 1427 | if (!tg_pt_gp_id) |
@@ -1441,7 +1429,7 @@ again: | |||
1441 | 1429 | ||
1442 | pr_err("ALUA Target Port Group ID: %hu already" | 1430 | pr_err("ALUA Target Port Group ID: %hu already" |
1443 | " exists, ignoring request\n", tg_pt_gp_id); | 1431 | " exists, ignoring request\n", tg_pt_gp_id); |
1444 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1432 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1445 | return -EINVAL; | 1433 | return -EINVAL; |
1446 | } | 1434 | } |
1447 | } | 1435 | } |
@@ -1449,9 +1437,9 @@ again: | |||
1449 | tg_pt_gp->tg_pt_gp_id = tg_pt_gp_id_tmp; | 1437 | tg_pt_gp->tg_pt_gp_id = tg_pt_gp_id_tmp; |
1450 | tg_pt_gp->tg_pt_gp_valid_id = 1; | 1438 | tg_pt_gp->tg_pt_gp_valid_id = 1; |
1451 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, | 1439 | list_add_tail(&tg_pt_gp->tg_pt_gp_list, |
1452 | &su_dev->t10_alua.tg_pt_gps_list); | 1440 | &dev->t10_alua.tg_pt_gps_list); |
1453 | su_dev->t10_alua.alua_tg_pt_gps_count++; | 1441 | dev->t10_alua.alua_tg_pt_gps_count++; |
1454 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1442 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1455 | 1443 | ||
1456 | return 0; | 1444 | return 0; |
1457 | } | 1445 | } |
@@ -1480,8 +1468,9 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( | |||
1480 | void core_alua_free_tg_pt_gp( | 1468 | void core_alua_free_tg_pt_gp( |
1481 | struct t10_alua_tg_pt_gp *tg_pt_gp) | 1469 | struct t10_alua_tg_pt_gp *tg_pt_gp) |
1482 | { | 1470 | { |
1483 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 1471 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
1484 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *tg_pt_gp_mem_tmp; | 1472 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *tg_pt_gp_mem_tmp; |
1473 | |||
1485 | /* | 1474 | /* |
1486 | * Once we have reached this point, config_item_put() has already | 1475 | * Once we have reached this point, config_item_put() has already |
1487 | * been called from target_core_alua_drop_tg_pt_gp(). | 1476 | * been called from target_core_alua_drop_tg_pt_gp(). |
@@ -1490,10 +1479,11 @@ void core_alua_free_tg_pt_gp( | |||
1490 | * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS | 1479 | * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS |
1491 | * can be made while we are releasing struct t10_alua_tg_pt_gp. | 1480 | * can be made while we are releasing struct t10_alua_tg_pt_gp. |
1492 | */ | 1481 | */ |
1493 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1482 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1494 | list_del(&tg_pt_gp->tg_pt_gp_list); | 1483 | list_del(&tg_pt_gp->tg_pt_gp_list); |
1495 | su_dev->t10_alua.alua_tg_pt_gps_counter--; | 1484 | dev->t10_alua.alua_tg_pt_gps_counter--; |
1496 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1485 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1486 | |||
1497 | /* | 1487 | /* |
1498 | * Allow a struct t10_alua_tg_pt_gp_member * referenced by | 1488 | * Allow a struct t10_alua_tg_pt_gp_member * referenced by |
1499 | * core_alua_get_tg_pt_gp_by_name() in | 1489 | * core_alua_get_tg_pt_gp_by_name() in |
@@ -1502,6 +1492,7 @@ void core_alua_free_tg_pt_gp( | |||
1502 | */ | 1492 | */ |
1503 | while (atomic_read(&tg_pt_gp->tg_pt_gp_ref_cnt)) | 1493 | while (atomic_read(&tg_pt_gp->tg_pt_gp_ref_cnt)) |
1504 | cpu_relax(); | 1494 | cpu_relax(); |
1495 | |||
1505 | /* | 1496 | /* |
1506 | * Release reference to struct t10_alua_tg_pt_gp from all associated | 1497 | * Release reference to struct t10_alua_tg_pt_gp from all associated |
1507 | * struct se_port. | 1498 | * struct se_port. |
@@ -1525,9 +1516,9 @@ void core_alua_free_tg_pt_gp( | |||
1525 | * default_tg_pt_gp. | 1516 | * default_tg_pt_gp. |
1526 | */ | 1517 | */ |
1527 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1518 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
1528 | if (tg_pt_gp != su_dev->t10_alua.default_tg_pt_gp) { | 1519 | if (tg_pt_gp != dev->t10_alua.default_tg_pt_gp) { |
1529 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, | 1520 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, |
1530 | su_dev->t10_alua.default_tg_pt_gp); | 1521 | dev->t10_alua.default_tg_pt_gp); |
1531 | } else | 1522 | } else |
1532 | tg_pt_gp_mem->tg_pt_gp = NULL; | 1523 | tg_pt_gp_mem->tg_pt_gp = NULL; |
1533 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1524 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -1541,14 +1532,9 @@ void core_alua_free_tg_pt_gp( | |||
1541 | 1532 | ||
1542 | void core_alua_free_tg_pt_gp_mem(struct se_port *port) | 1533 | void core_alua_free_tg_pt_gp_mem(struct se_port *port) |
1543 | { | 1534 | { |
1544 | struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev; | ||
1545 | struct t10_alua *alua = &su_dev->t10_alua; | ||
1546 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1535 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1547 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 1536 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
1548 | 1537 | ||
1549 | if (alua->alua_type != SPC3_ALUA_EMULATED) | ||
1550 | return; | ||
1551 | |||
1552 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 1538 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
1553 | if (!tg_pt_gp_mem) | 1539 | if (!tg_pt_gp_mem) |
1554 | return; | 1540 | return; |
@@ -1574,25 +1560,24 @@ void core_alua_free_tg_pt_gp_mem(struct se_port *port) | |||
1574 | } | 1560 | } |
1575 | 1561 | ||
1576 | static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name( | 1562 | static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name( |
1577 | struct se_subsystem_dev *su_dev, | 1563 | struct se_device *dev, const char *name) |
1578 | const char *name) | ||
1579 | { | 1564 | { |
1580 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1565 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1581 | struct config_item *ci; | 1566 | struct config_item *ci; |
1582 | 1567 | ||
1583 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1568 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1584 | list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list, | 1569 | list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list, |
1585 | tg_pt_gp_list) { | 1570 | tg_pt_gp_list) { |
1586 | if (!tg_pt_gp->tg_pt_gp_valid_id) | 1571 | if (!tg_pt_gp->tg_pt_gp_valid_id) |
1587 | continue; | 1572 | continue; |
1588 | ci = &tg_pt_gp->tg_pt_gp_group.cg_item; | 1573 | ci = &tg_pt_gp->tg_pt_gp_group.cg_item; |
1589 | if (!strcmp(config_item_name(ci), name)) { | 1574 | if (!strcmp(config_item_name(ci), name)) { |
1590 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 1575 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
1591 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1576 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1592 | return tg_pt_gp; | 1577 | return tg_pt_gp; |
1593 | } | 1578 | } |
1594 | } | 1579 | } |
1595 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1580 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1596 | 1581 | ||
1597 | return NULL; | 1582 | return NULL; |
1598 | } | 1583 | } |
@@ -1600,11 +1585,11 @@ static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name( | |||
1600 | static void core_alua_put_tg_pt_gp_from_name( | 1585 | static void core_alua_put_tg_pt_gp_from_name( |
1601 | struct t10_alua_tg_pt_gp *tg_pt_gp) | 1586 | struct t10_alua_tg_pt_gp *tg_pt_gp) |
1602 | { | 1587 | { |
1603 | struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev; | 1588 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
1604 | 1589 | ||
1605 | spin_lock(&su_dev->t10_alua.tg_pt_gps_lock); | 1590 | spin_lock(&dev->t10_alua.tg_pt_gps_lock); |
1606 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); | 1591 | atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt); |
1607 | spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock); | 1592 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1608 | } | 1593 | } |
1609 | 1594 | ||
1610 | /* | 1595 | /* |
@@ -1640,16 +1625,11 @@ static void __core_alua_drop_tg_pt_gp_mem( | |||
1640 | 1625 | ||
1641 | ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page) | 1626 | ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page) |
1642 | { | 1627 | { |
1643 | struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev; | ||
1644 | struct config_item *tg_pt_ci; | 1628 | struct config_item *tg_pt_ci; |
1645 | struct t10_alua *alua = &su_dev->t10_alua; | ||
1646 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1629 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1647 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 1630 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
1648 | ssize_t len = 0; | 1631 | ssize_t len = 0; |
1649 | 1632 | ||
1650 | if (alua->alua_type != SPC3_ALUA_EMULATED) | ||
1651 | return len; | ||
1652 | |||
1653 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | 1633 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
1654 | if (!tg_pt_gp_mem) | 1634 | if (!tg_pt_gp_mem) |
1655 | return len; | 1635 | return len; |
@@ -1683,7 +1663,7 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1683 | { | 1663 | { |
1684 | struct se_portal_group *tpg; | 1664 | struct se_portal_group *tpg; |
1685 | struct se_lun *lun; | 1665 | struct se_lun *lun; |
1686 | struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev; | 1666 | struct se_device *dev = port->sep_lun->lun_se_dev; |
1687 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *tg_pt_gp_new = NULL; | 1667 | struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *tg_pt_gp_new = NULL; |
1688 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; | 1668 | struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; |
1689 | unsigned char buf[TG_PT_GROUP_NAME_BUF]; | 1669 | unsigned char buf[TG_PT_GROUP_NAME_BUF]; |
@@ -1692,13 +1672,9 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1692 | tpg = port->sep_tpg; | 1672 | tpg = port->sep_tpg; |
1693 | lun = port->sep_lun; | 1673 | lun = port->sep_lun; |
1694 | 1674 | ||
1695 | if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) { | 1675 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; |
1696 | pr_warn("SPC3_ALUA_EMULATED not enabled for" | 1676 | if (!tg_pt_gp_mem) |
1697 | " %s/tpgt_%hu/%s\n", tpg->se_tpg_tfo->tpg_get_wwn(tpg), | 1677 | return 0; |
1698 | tpg->se_tpg_tfo->tpg_get_tag(tpg), | ||
1699 | config_item_name(&lun->lun_group.cg_item)); | ||
1700 | return -EINVAL; | ||
1701 | } | ||
1702 | 1678 | ||
1703 | if (count > TG_PT_GROUP_NAME_BUF) { | 1679 | if (count > TG_PT_GROUP_NAME_BUF) { |
1704 | pr_err("ALUA Target Port Group alias too large!\n"); | 1680 | pr_err("ALUA Target Port Group alias too large!\n"); |
@@ -1716,18 +1692,11 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1716 | * struct t10_alua_tg_pt_gp. This reference is released with | 1692 | * struct t10_alua_tg_pt_gp. This reference is released with |
1717 | * core_alua_put_tg_pt_gp_from_name() below. | 1693 | * core_alua_put_tg_pt_gp_from_name() below. |
1718 | */ | 1694 | */ |
1719 | tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(su_dev, | 1695 | tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(dev, |
1720 | strstrip(buf)); | 1696 | strstrip(buf)); |
1721 | if (!tg_pt_gp_new) | 1697 | if (!tg_pt_gp_new) |
1722 | return -ENODEV; | 1698 | return -ENODEV; |
1723 | } | 1699 | } |
1724 | tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; | ||
1725 | if (!tg_pt_gp_mem) { | ||
1726 | if (tg_pt_gp_new) | ||
1727 | core_alua_put_tg_pt_gp_from_name(tg_pt_gp_new); | ||
1728 | pr_err("NULL struct se_port->sep_alua_tg_pt_gp_mem pointer\n"); | ||
1729 | return -EINVAL; | ||
1730 | } | ||
1731 | 1700 | ||
1732 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1701 | spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
1733 | tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; | 1702 | tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; |
@@ -1750,7 +1719,7 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1750 | 1719 | ||
1751 | __core_alua_drop_tg_pt_gp_mem(tg_pt_gp_mem, tg_pt_gp); | 1720 | __core_alua_drop_tg_pt_gp_mem(tg_pt_gp_mem, tg_pt_gp); |
1752 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, | 1721 | __core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem, |
1753 | su_dev->t10_alua.default_tg_pt_gp); | 1722 | dev->t10_alua.default_tg_pt_gp); |
1754 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); | 1723 | spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); |
1755 | 1724 | ||
1756 | return count; | 1725 | return count; |
@@ -2054,32 +2023,12 @@ ssize_t core_alua_store_secondary_write_metadata( | |||
2054 | return count; | 2023 | return count; |
2055 | } | 2024 | } |
2056 | 2025 | ||
2057 | int core_setup_alua(struct se_device *dev, int force_pt) | 2026 | int core_setup_alua(struct se_device *dev) |
2058 | { | 2027 | { |
2059 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | 2028 | if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV && |
2060 | struct t10_alua *alua = &su_dev->t10_alua; | 2029 | !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { |
2061 | struct t10_alua_lu_gp_member *lu_gp_mem; | 2030 | struct t10_alua_lu_gp_member *lu_gp_mem; |
2062 | /* | 2031 | |
2063 | * If this device is from Target_Core_Mod/pSCSI, use the ALUA logic | ||
2064 | * of the Underlying SCSI hardware. In Linux/SCSI terms, this can | ||
2065 | * cause a problem because libata and some SATA RAID HBAs appear | ||
2066 | * under Linux/SCSI, but emulate SCSI logic themselves. | ||
2067 | */ | ||
2068 | if (((dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) && | ||
2069 | !(dev->se_sub_dev->se_dev_attrib.emulate_alua)) || force_pt) { | ||
2070 | alua->alua_type = SPC_ALUA_PASSTHROUGH; | ||
2071 | alua->alua_state_check = &core_alua_state_check_nop; | ||
2072 | pr_debug("%s: Using SPC_ALUA_PASSTHROUGH, no ALUA" | ||
2073 | " emulation\n", dev->transport->name); | ||
2074 | return 0; | ||
2075 | } | ||
2076 | /* | ||
2077 | * If SPC-3 or above is reported by real or emulated struct se_device, | ||
2078 | * use emulated ALUA. | ||
2079 | */ | ||
2080 | if (dev->transport->get_device_rev(dev) >= SCSI_3) { | ||
2081 | pr_debug("%s: Enabling ALUA Emulation for SPC-3" | ||
2082 | " device\n", dev->transport->name); | ||
2083 | /* | 2032 | /* |
2084 | * Associate this struct se_device with the default ALUA | 2033 | * Associate this struct se_device with the default ALUA |
2085 | * LUN Group. | 2034 | * LUN Group. |
@@ -2088,8 +2037,6 @@ int core_setup_alua(struct se_device *dev, int force_pt) | |||
2088 | if (IS_ERR(lu_gp_mem)) | 2037 | if (IS_ERR(lu_gp_mem)) |
2089 | return PTR_ERR(lu_gp_mem); | 2038 | return PTR_ERR(lu_gp_mem); |
2090 | 2039 | ||
2091 | alua->alua_type = SPC3_ALUA_EMULATED; | ||
2092 | alua->alua_state_check = &core_alua_state_check; | ||
2093 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); | 2040 | spin_lock(&lu_gp_mem->lu_gp_mem_lock); |
2094 | __core_alua_attach_lu_gp_mem(lu_gp_mem, | 2041 | __core_alua_attach_lu_gp_mem(lu_gp_mem, |
2095 | default_lu_gp); | 2042 | default_lu_gp); |
@@ -2098,11 +2045,6 @@ int core_setup_alua(struct se_device *dev, int force_pt) | |||
2098 | pr_debug("%s: Adding to default ALUA LU Group:" | 2045 | pr_debug("%s: Adding to default ALUA LU Group:" |
2099 | " core/alua/lu_gps/default_lu_gp\n", | 2046 | " core/alua/lu_gps/default_lu_gp\n", |
2100 | dev->transport->name); | 2047 | dev->transport->name); |
2101 | } else { | ||
2102 | alua->alua_type = SPC2_ALUA_DISABLED; | ||
2103 | alua->alua_state_check = &core_alua_state_check_nop; | ||
2104 | pr_debug("%s: Disabling ALUA Emulation for SPC-2" | ||
2105 | " device\n", dev->transport->name); | ||
2106 | } | 2048 | } |
2107 | 2049 | ||
2108 | return 0; | 2050 | return 0; |