diff options
author | Hannes Reinecke <hare@suse.de> | 2013-12-17 03:18:49 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-01-10 00:48:17 -0500 |
commit | c66094bf325ee406b92298d73089ee25484a0263 (patch) | |
tree | cfa2fb231dbd3e120ad2d75f96c250c24233978a | |
parent | fbfe858fea2a45df6339eb03dd1715b51f1bdc92 (diff) |
target_core_alua: Referrals infrastructure
Add infrastructure for referrals.
v2 changes:
- Fix unsigned long long division in core_alua_state_lba_dependent on
32-bit (Fengguang + Chen + Hannes)
- Fix compile warning in core_alua_state_lba_dependent (nab)
- Convert segment_* + sectors variables in core_alua_state_lba_dependent
to u64 (Hannes)
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_alua.c | 154 | ||||
-rw-r--r-- | drivers/target/target_core_alua.h | 4 | ||||
-rw-r--r-- | drivers/target/target_core_configfs.c | 9 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 2 | ||||
-rw-r--r-- | drivers/target/target_core_sbc.c | 5 | ||||
-rw-r--r-- | drivers/target/target_core_spc.c | 20 | ||||
-rw-r--r-- | include/scsi/scsi.h | 1 | ||||
-rw-r--r-- | include/target/target_core_base.h | 18 |
8 files changed, 210 insertions, 3 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 01f0c71891d6..0843c8f4b94e 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -58,6 +58,75 @@ static LIST_HEAD(lu_gps_list); | |||
58 | struct t10_alua_lu_gp *default_lu_gp; | 58 | struct t10_alua_lu_gp *default_lu_gp; |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * REPORT REFERRALS | ||
62 | * | ||
63 | * See sbc3r35 section 5.23 | ||
64 | */ | ||
65 | sense_reason_t | ||
66 | target_emulate_report_referrals(struct se_cmd *cmd) | ||
67 | { | ||
68 | struct se_device *dev = cmd->se_dev; | ||
69 | struct t10_alua_lba_map *map; | ||
70 | struct t10_alua_lba_map_member *map_mem; | ||
71 | unsigned char *buf; | ||
72 | u32 rd_len = 0, off; | ||
73 | |||
74 | if (cmd->data_length < 4) { | ||
75 | pr_warn("REPORT REFERRALS allocation length %u too" | ||
76 | " small\n", cmd->data_length); | ||
77 | return TCM_INVALID_CDB_FIELD; | ||
78 | } | ||
79 | |||
80 | buf = transport_kmap_data_sg(cmd); | ||
81 | if (!buf) | ||
82 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
83 | |||
84 | off = 4; | ||
85 | spin_lock(&dev->t10_alua.lba_map_lock); | ||
86 | if (list_empty(&dev->t10_alua.lba_map_list)) { | ||
87 | spin_unlock(&dev->t10_alua.lba_map_lock); | ||
88 | transport_kunmap_data_sg(cmd); | ||
89 | |||
90 | return TCM_UNSUPPORTED_SCSI_OPCODE; | ||
91 | } | ||
92 | |||
93 | list_for_each_entry(map, &dev->t10_alua.lba_map_list, | ||
94 | lba_map_list) { | ||
95 | int desc_num = off + 3; | ||
96 | int pg_num; | ||
97 | |||
98 | off += 4; | ||
99 | put_unaligned_be64(map->lba_map_first_lba, &buf[off]); | ||
100 | off += 8; | ||
101 | put_unaligned_be64(map->lba_map_last_lba, &buf[off]); | ||
102 | off += 8; | ||
103 | rd_len += 20; | ||
104 | pg_num = 0; | ||
105 | list_for_each_entry(map_mem, &map->lba_map_mem_list, | ||
106 | lba_map_mem_list) { | ||
107 | buf[off++] = map_mem->lba_map_mem_alua_state & 0x0f; | ||
108 | off++; | ||
109 | buf[off++] = (map_mem->lba_map_mem_alua_pg_id >> 8) & 0xff; | ||
110 | buf[off++] = (map_mem->lba_map_mem_alua_pg_id & 0xff); | ||
111 | rd_len += 4; | ||
112 | pg_num++; | ||
113 | } | ||
114 | buf[desc_num] = pg_num; | ||
115 | } | ||
116 | spin_unlock(&dev->t10_alua.lba_map_lock); | ||
117 | |||
118 | /* | ||
119 | * Set the RETURN DATA LENGTH set in the header of the DataIN Payload | ||
120 | */ | ||
121 | put_unaligned_be16(rd_len, &buf[2]); | ||
122 | |||
123 | transport_kunmap_data_sg(cmd); | ||
124 | |||
125 | target_complete_cmd(cmd, GOOD); | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | /* | ||
61 | * REPORT_TARGET_PORT_GROUPS | 130 | * REPORT_TARGET_PORT_GROUPS |
62 | * | 131 | * |
63 | * See spc4r17 section 6.27 | 132 | * See spc4r17 section 6.27 |
@@ -391,6 +460,81 @@ static inline int core_alua_state_nonoptimized( | |||
391 | return 0; | 460 | return 0; |
392 | } | 461 | } |
393 | 462 | ||
463 | static inline int core_alua_state_lba_dependent( | ||
464 | struct se_cmd *cmd, | ||
465 | struct t10_alua_tg_pt_gp *tg_pt_gp, | ||
466 | u8 *alua_ascq) | ||
467 | { | ||
468 | struct se_device *dev = cmd->se_dev; | ||
469 | u64 segment_size, segment_mult, sectors, lba; | ||
470 | |||
471 | /* Only need to check for cdb actually containing LBAs */ | ||
472 | if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB)) | ||
473 | return 0; | ||
474 | |||
475 | spin_lock(&dev->t10_alua.lba_map_lock); | ||
476 | segment_size = dev->t10_alua.lba_map_segment_size; | ||
477 | segment_mult = dev->t10_alua.lba_map_segment_multiplier; | ||
478 | sectors = cmd->data_length / dev->dev_attrib.block_size; | ||
479 | |||
480 | lba = cmd->t_task_lba; | ||
481 | while (lba < cmd->t_task_lba + sectors) { | ||
482 | struct t10_alua_lba_map *cur_map = NULL, *map; | ||
483 | struct t10_alua_lba_map_member *map_mem; | ||
484 | |||
485 | list_for_each_entry(map, &dev->t10_alua.lba_map_list, | ||
486 | lba_map_list) { | ||
487 | u64 start_lba, last_lba; | ||
488 | u64 first_lba = map->lba_map_first_lba; | ||
489 | |||
490 | if (segment_mult) { | ||
491 | u64 tmp = lba; | ||
492 | start_lba = sector_div(tmp, segment_size * segment_mult); | ||
493 | |||
494 | last_lba = first_lba + segment_size - 1; | ||
495 | if (start_lba >= first_lba && | ||
496 | start_lba <= last_lba) { | ||
497 | lba += segment_size; | ||
498 | cur_map = map; | ||
499 | break; | ||
500 | } | ||
501 | } else { | ||
502 | last_lba = map->lba_map_last_lba; | ||
503 | if (lba >= first_lba && lba <= last_lba) { | ||
504 | lba = last_lba + 1; | ||
505 | cur_map = map; | ||
506 | break; | ||
507 | } | ||
508 | } | ||
509 | } | ||
510 | if (!cur_map) { | ||
511 | spin_unlock(&dev->t10_alua.lba_map_lock); | ||
512 | *alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE; | ||
513 | return 1; | ||
514 | } | ||
515 | list_for_each_entry(map_mem, &cur_map->lba_map_mem_list, | ||
516 | lba_map_mem_list) { | ||
517 | if (map_mem->lba_map_mem_alua_pg_id != | ||
518 | tg_pt_gp->tg_pt_gp_id) | ||
519 | continue; | ||
520 | switch(map_mem->lba_map_mem_alua_state) { | ||
521 | case ALUA_ACCESS_STATE_STANDBY: | ||
522 | spin_unlock(&dev->t10_alua.lba_map_lock); | ||
523 | *alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY; | ||
524 | return 1; | ||
525 | case ALUA_ACCESS_STATE_UNAVAILABLE: | ||
526 | spin_unlock(&dev->t10_alua.lba_map_lock); | ||
527 | *alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE; | ||
528 | return 1; | ||
529 | default: | ||
530 | break; | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | spin_unlock(&dev->t10_alua.lba_map_lock); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
394 | static inline int core_alua_state_standby( | 538 | static inline int core_alua_state_standby( |
395 | struct se_cmd *cmd, | 539 | struct se_cmd *cmd, |
396 | unsigned char *cdb, | 540 | unsigned char *cdb, |
@@ -588,6 +732,9 @@ target_alua_state_check(struct se_cmd *cmd) | |||
588 | case ALUA_ACCESS_STATE_TRANSITION: | 732 | case ALUA_ACCESS_STATE_TRANSITION: |
589 | ret = core_alua_state_transition(cmd, cdb, &alua_ascq); | 733 | ret = core_alua_state_transition(cmd, cdb, &alua_ascq); |
590 | break; | 734 | break; |
735 | case ALUA_ACCESS_STATE_LBA_DEPENDENT: | ||
736 | ret = core_alua_state_lba_dependent(cmd, tg_pt_gp, &alua_ascq); | ||
737 | break; | ||
591 | /* | 738 | /* |
592 | * OFFLINE is a secondary ALUA target port group access state, that is | 739 | * OFFLINE is a secondary ALUA target port group access state, that is |
593 | * handled above with struct se_port->sep_tg_pt_secondary_offline=1 | 740 | * handled above with struct se_port->sep_tg_pt_secondary_offline=1 |
@@ -650,6 +797,11 @@ core_alua_check_transition(int state, int valid, int *primary) | |||
650 | goto not_supported; | 797 | goto not_supported; |
651 | *primary = 1; | 798 | *primary = 1; |
652 | break; | 799 | break; |
800 | case ALUA_ACCESS_STATE_LBA_DEPENDENT: | ||
801 | if (!(valid & ALUA_LBD_SUP)) | ||
802 | goto not_supported; | ||
803 | *primary = 1; | ||
804 | break; | ||
653 | case ALUA_ACCESS_STATE_OFFLINE: | 805 | case ALUA_ACCESS_STATE_OFFLINE: |
654 | /* | 806 | /* |
655 | * OFFLINE state is defined as a secondary target port | 807 | * OFFLINE state is defined as a secondary target port |
@@ -685,6 +837,8 @@ static char *core_alua_dump_state(int state) | |||
685 | return "Active/Optimized"; | 837 | return "Active/Optimized"; |
686 | case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED: | 838 | case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED: |
687 | return "Active/NonOptimized"; | 839 | return "Active/NonOptimized"; |
840 | case ALUA_ACCESS_STATE_LBA_DEPENDENT: | ||
841 | return "LBA Dependent"; | ||
688 | case ALUA_ACCESS_STATE_STANDBY: | 842 | case ALUA_ACCESS_STATE_STANDBY: |
689 | return "Standby"; | 843 | return "Standby"; |
690 | case ALUA_ACCESS_STATE_UNAVAILABLE: | 844 | case ALUA_ACCESS_STATE_UNAVAILABLE: |
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h index 1a152cd59471..47950cdc6f8b 100644 --- a/drivers/target/target_core_alua.h +++ b/drivers/target/target_core_alua.h | |||
@@ -13,12 +13,13 @@ | |||
13 | /* | 13 | /* |
14 | * ASYMMETRIC ACCESS STATE field | 14 | * ASYMMETRIC ACCESS STATE field |
15 | * | 15 | * |
16 | * from spc4r17 section 6.27 Table 245 | 16 | * from spc4r36j section 6.37 Table 307 |
17 | */ | 17 | */ |
18 | #define ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED 0x0 | 18 | #define ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED 0x0 |
19 | #define ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED 0x1 | 19 | #define ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED 0x1 |
20 | #define ALUA_ACCESS_STATE_STANDBY 0x2 | 20 | #define ALUA_ACCESS_STATE_STANDBY 0x2 |
21 | #define ALUA_ACCESS_STATE_UNAVAILABLE 0x3 | 21 | #define ALUA_ACCESS_STATE_UNAVAILABLE 0x3 |
22 | #define ALUA_ACCESS_STATE_LBA_DEPENDENT 0x4 | ||
22 | #define ALUA_ACCESS_STATE_OFFLINE 0xe | 23 | #define ALUA_ACCESS_STATE_OFFLINE 0xe |
23 | #define ALUA_ACCESS_STATE_TRANSITION 0xf | 24 | #define ALUA_ACCESS_STATE_TRANSITION 0xf |
24 | 25 | ||
@@ -88,6 +89,7 @@ extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache; | |||
88 | 89 | ||
89 | extern sense_reason_t target_emulate_report_target_port_groups(struct se_cmd *); | 90 | extern sense_reason_t target_emulate_report_target_port_groups(struct se_cmd *); |
90 | extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *); | 91 | extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *); |
92 | extern sense_reason_t target_emulate_report_referrals(struct se_cmd *); | ||
91 | extern int core_alua_check_nonop_delay(struct se_cmd *); | 93 | extern int core_alua_check_nonop_delay(struct se_cmd *); |
92 | extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *, | 94 | extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *, |
93 | struct se_device *, struct se_port *, | 95 | struct se_device *, struct se_port *, |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index a1c23d10468e..e0a47f524700 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -2054,6 +2054,13 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state( | |||
2054 | " transition while TPGS_IMPLICIT_ALUA is disabled\n"); | 2054 | " transition while TPGS_IMPLICIT_ALUA is disabled\n"); |
2055 | return -EINVAL; | 2055 | return -EINVAL; |
2056 | } | 2056 | } |
2057 | if (tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA && | ||
2058 | new_state == ALUA_ACCESS_STATE_LBA_DEPENDENT) { | ||
2059 | /* LBA DEPENDENT is only allowed with implicit ALUA */ | ||
2060 | pr_err("Unable to process implicit configfs ALUA transition" | ||
2061 | " while explicit ALUA management is enabled\n"); | ||
2062 | return -EINVAL; | ||
2063 | } | ||
2057 | 2064 | ||
2058 | ret = core_alua_do_port_transition(tg_pt_gp, dev, | 2065 | ret = core_alua_do_port_transition(tg_pt_gp, dev, |
2059 | NULL, NULL, new_state, 0); | 2066 | NULL, NULL, new_state, 0); |
@@ -2188,7 +2195,7 @@ SE_DEV_ALUA_SUPPORT_STATE_SHOW(lba_dependent, | |||
2188 | tg_pt_gp_alua_supported_states, ALUA_LBD_SUP); | 2195 | tg_pt_gp_alua_supported_states, ALUA_LBD_SUP); |
2189 | SE_DEV_ALUA_SUPPORT_STATE_STORE(lba_dependent, | 2196 | SE_DEV_ALUA_SUPPORT_STATE_STORE(lba_dependent, |
2190 | tg_pt_gp_alua_supported_states, ALUA_LBD_SUP); | 2197 | tg_pt_gp_alua_supported_states, ALUA_LBD_SUP); |
2191 | SE_DEV_ALUA_TG_PT_ATTR(alua_support_lba_dependent, S_IRUGO | S_IWUSR); | 2198 | SE_DEV_ALUA_TG_PT_ATTR(alua_support_lba_dependent, S_IRUGO); |
2192 | 2199 | ||
2193 | SE_DEV_ALUA_SUPPORT_STATE_SHOW(unavailable, | 2200 | SE_DEV_ALUA_SUPPORT_STATE_SHOW(unavailable, |
2194 | tg_pt_gp_alua_supported_states, ALUA_U_SUP); | 2201 | tg_pt_gp_alua_supported_states, ALUA_U_SUP); |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index dbd78a176ddb..88b4fb2f6e1a 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1439,6 +1439,8 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
1439 | spin_lock_init(&dev->t10_pr.aptpl_reg_lock); | 1439 | spin_lock_init(&dev->t10_pr.aptpl_reg_lock); |
1440 | INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); | 1440 | INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list); |
1441 | spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); | 1441 | spin_lock_init(&dev->t10_alua.tg_pt_gps_lock); |
1442 | INIT_LIST_HEAD(&dev->t10_alua.lba_map_list); | ||
1443 | spin_lock_init(&dev->t10_alua.lba_map_lock); | ||
1442 | 1444 | ||
1443 | dev->t10_wwn.t10_dev = dev; | 1445 | dev->t10_wwn.t10_dev = dev; |
1444 | dev->t10_alua.t10_dev = dev; | 1446 | dev->t10_alua.t10_dev = dev; |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 52ae54e60105..6863dbe0aadf 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #include "target_core_internal.h" | 34 | #include "target_core_internal.h" |
35 | #include "target_core_ua.h" | 35 | #include "target_core_ua.h" |
36 | 36 | #include "target_core_alua.h" | |
37 | 37 | ||
38 | static sense_reason_t | 38 | static sense_reason_t |
39 | sbc_emulate_readcapacity(struct se_cmd *cmd) | 39 | sbc_emulate_readcapacity(struct se_cmd *cmd) |
@@ -731,6 +731,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
731 | case SAI_READ_CAPACITY_16: | 731 | case SAI_READ_CAPACITY_16: |
732 | cmd->execute_cmd = sbc_emulate_readcapacity_16; | 732 | cmd->execute_cmd = sbc_emulate_readcapacity_16; |
733 | break; | 733 | break; |
734 | case SAI_REPORT_REFERRALS: | ||
735 | cmd->execute_cmd = target_emulate_report_referrals; | ||
736 | break; | ||
734 | default: | 737 | default: |
735 | pr_err("Unsupported SA: 0x%02x\n", | 738 | pr_err("Unsupported SA: 0x%02x\n", |
736 | cmd->t_task_cdb[1] & 0x1f); | 739 | cmd->t_task_cdb[1] & 0x1f); |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 39054d9029f3..f9889fd82994 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -476,6 +476,11 @@ spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | |||
476 | /* If WriteCache emulation is enabled, set V_SUP */ | 476 | /* If WriteCache emulation is enabled, set V_SUP */ |
477 | if (spc_check_dev_wce(dev)) | 477 | if (spc_check_dev_wce(dev)) |
478 | buf[6] = 0x01; | 478 | buf[6] = 0x01; |
479 | /* If an LBA map is present set R_SUP */ | ||
480 | spin_lock(&cmd->se_dev->t10_alua.lba_map_lock); | ||
481 | if (!list_empty(&dev->t10_alua.lba_map_list)) | ||
482 | buf[8] = 0x10; | ||
483 | spin_unlock(&cmd->se_dev->t10_alua.lba_map_lock); | ||
479 | return 0; | 484 | return 0; |
480 | } | 485 | } |
481 | 486 | ||
@@ -634,6 +639,20 @@ spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | |||
634 | return 0; | 639 | return 0; |
635 | } | 640 | } |
636 | 641 | ||
642 | /* Referrals VPD page */ | ||
643 | static sense_reason_t | ||
644 | spc_emulate_evpd_b3(struct se_cmd *cmd, unsigned char *buf) | ||
645 | { | ||
646 | struct se_device *dev = cmd->se_dev; | ||
647 | |||
648 | buf[0] = dev->transport->get_device_type(dev); | ||
649 | buf[3] = 0x0c; | ||
650 | put_unaligned_be32(dev->t10_alua.lba_map_segment_size, &buf[8]); | ||
651 | put_unaligned_be32(dev->t10_alua.lba_map_segment_size, &buf[12]); | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
637 | static sense_reason_t | 656 | static sense_reason_t |
638 | spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); | 657 | spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); |
639 | 658 | ||
@@ -648,6 +667,7 @@ static struct { | |||
648 | { .page = 0xb0, .emulate = spc_emulate_evpd_b0 }, | 667 | { .page = 0xb0, .emulate = spc_emulate_evpd_b0 }, |
649 | { .page = 0xb1, .emulate = spc_emulate_evpd_b1 }, | 668 | { .page = 0xb1, .emulate = spc_emulate_evpd_b1 }, |
650 | { .page = 0xb2, .emulate = spc_emulate_evpd_b2 }, | 669 | { .page = 0xb2, .emulate = spc_emulate_evpd_b2 }, |
670 | { .page = 0xb3, .emulate = spc_emulate_evpd_b3 }, | ||
651 | }; | 671 | }; |
652 | 672 | ||
653 | /* supported vital product data pages */ | 673 | /* supported vital product data pages */ |
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 66d42edfb3fc..0a4edfe8af51 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h | |||
@@ -155,6 +155,7 @@ enum scsi_timeouts { | |||
155 | /* values for service action in */ | 155 | /* values for service action in */ |
156 | #define SAI_READ_CAPACITY_16 0x10 | 156 | #define SAI_READ_CAPACITY_16 0x10 |
157 | #define SAI_GET_LBA_STATUS 0x12 | 157 | #define SAI_GET_LBA_STATUS 0x12 |
158 | #define SAI_REPORT_REFERRALS 0x13 | ||
158 | /* values for VARIABLE_LENGTH_CMD service action codes | 159 | /* values for VARIABLE_LENGTH_CMD service action codes |
159 | * see spc4r17 Section D.3.5, table D.7 and D.8 */ | 160 | * see spc4r17 Section D.3.5, table D.7 and D.8 */ |
160 | #define VLC_SA_RECEIVE_CREDENTIAL 0x1800 | 161 | #define VLC_SA_RECEIVE_CREDENTIAL 0x1800 |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 6c8001516c6d..1ba19a4bec33 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -247,10 +247,28 @@ typedef enum { | |||
247 | 247 | ||
248 | struct se_cmd; | 248 | struct se_cmd; |
249 | 249 | ||
250 | struct t10_alua_lba_map_member { | ||
251 | struct list_head lba_map_mem_list; | ||
252 | int lba_map_mem_alua_state; | ||
253 | int lba_map_mem_alua_pg_id; | ||
254 | }; | ||
255 | |||
256 | struct t10_alua_lba_map { | ||
257 | u64 lba_map_first_lba; | ||
258 | u64 lba_map_last_lba; | ||
259 | struct list_head lba_map_list; | ||
260 | struct list_head lba_map_mem_list; | ||
261 | }; | ||
262 | |||
250 | struct t10_alua { | 263 | struct t10_alua { |
251 | /* ALUA Target Port Group ID */ | 264 | /* ALUA Target Port Group ID */ |
252 | u16 alua_tg_pt_gps_counter; | 265 | u16 alua_tg_pt_gps_counter; |
253 | u32 alua_tg_pt_gps_count; | 266 | u32 alua_tg_pt_gps_count; |
267 | /* Referrals support */ | ||
268 | spinlock_t lba_map_lock; | ||
269 | u32 lba_map_segment_size; | ||
270 | u32 lba_map_segment_multiplier; | ||
271 | struct list_head lba_map_list; | ||
254 | spinlock_t tg_pt_gps_lock; | 272 | spinlock_t tg_pt_gps_lock; |
255 | struct se_device *t10_dev; | 273 | struct se_device *t10_dev; |
256 | /* Used for default ALUA Target Port Group */ | 274 | /* Used for default ALUA Target Port Group */ |