diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-10-10 17:37:15 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-06 23:55:45 -0500 |
commit | d977f4377fbc396b888e12fdb3b13118b09ca7db (patch) | |
tree | f3de282b1df951ec599908e24590dbcbac5b9047 /drivers/target | |
parent | 019c4ca621488739b1bfb7597a14ac7f0cbcc908 (diff) |
target: simplify reservations code
We do not support host-level reservations for the pscsi backend, and all
virtual backends are newere than SCSI-2, so just make the combined
SPC-3 + SCSI-2 support the only supported variant and kill the switches
for the different implementations, given that this code handles the no-op
version just fine.
(hch: Update DRF_SPC2_RESERVATIONS lock usage)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/target_core_configfs.c | 158 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 3 | ||||
-rw-r--r-- | drivers/target/target_core_pr.c | 192 | ||||
-rw-r--r-- | drivers/target/target_core_pr.h | 2 | ||||
-rw-r--r-- | drivers/target/target_core_spc.c | 19 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 22 |
6 files changed, 127 insertions, 269 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 7272016ed05f..3d5570da41eb 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -970,13 +970,8 @@ static struct target_core_dev_pr_attribute target_core_dev_pr_##_name = \ | |||
970 | __CONFIGFS_EATTR_RO(_name, \ | 970 | __CONFIGFS_EATTR_RO(_name, \ |
971 | target_core_dev_pr_show_attr_##_name); | 971 | target_core_dev_pr_show_attr_##_name); |
972 | 972 | ||
973 | /* | 973 | static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev, |
974 | * res_holder | 974 | char *page) |
975 | */ | ||
976 | static ssize_t target_core_dev_pr_show_spc3_res( | ||
977 | struct se_device *dev, | ||
978 | char *page, | ||
979 | ssize_t *len) | ||
980 | { | 975 | { |
981 | struct se_node_acl *se_nacl; | 976 | struct se_node_acl *se_nacl; |
982 | struct t10_pr_registration *pr_reg; | 977 | struct t10_pr_registration *pr_reg; |
@@ -985,68 +980,52 @@ static ssize_t target_core_dev_pr_show_spc3_res( | |||
985 | 980 | ||
986 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 981 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
987 | 982 | ||
988 | spin_lock(&dev->dev_reservation_lock); | ||
989 | pr_reg = dev->dev_pr_res_holder; | 983 | pr_reg = dev->dev_pr_res_holder; |
990 | if (!pr_reg) { | 984 | if (!pr_reg) |
991 | *len += sprintf(page + *len, "No SPC-3 Reservation holder\n"); | 985 | return sprintf(page, "No SPC-3 Reservation holder\n"); |
992 | spin_unlock(&dev->dev_reservation_lock); | 986 | |
993 | return *len; | ||
994 | } | ||
995 | se_nacl = pr_reg->pr_reg_nacl; | 987 | se_nacl = pr_reg->pr_reg_nacl; |
996 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], | 988 | prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0], |
997 | PR_REG_ISID_ID_LEN); | 989 | PR_REG_ISID_ID_LEN); |
998 | 990 | ||
999 | *len += sprintf(page + *len, "SPC-3 Reservation: %s Initiator: %s%s\n", | 991 | return sprintf(page, "SPC-3 Reservation: %s Initiator: %s%s\n", |
1000 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), | 992 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), |
1001 | se_nacl->initiatorname, (prf_isid) ? &i_buf[0] : ""); | 993 | se_nacl->initiatorname, (prf_isid) ? &i_buf[0] : ""); |
1002 | spin_unlock(&dev->dev_reservation_lock); | ||
1003 | |||
1004 | return *len; | ||
1005 | } | 994 | } |
1006 | 995 | ||
1007 | static ssize_t target_core_dev_pr_show_spc2_res( | 996 | static ssize_t target_core_dev_pr_show_spc2_res(struct se_device *dev, |
1008 | struct se_device *dev, | 997 | char *page) |
1009 | char *page, | ||
1010 | ssize_t *len) | ||
1011 | { | 998 | { |
1012 | struct se_node_acl *se_nacl; | 999 | struct se_node_acl *se_nacl; |
1000 | ssize_t len; | ||
1013 | 1001 | ||
1014 | spin_lock(&dev->dev_reservation_lock); | ||
1015 | se_nacl = dev->dev_reserved_node_acl; | 1002 | se_nacl = dev->dev_reserved_node_acl; |
1016 | if (!se_nacl) { | 1003 | if (se_nacl) { |
1017 | *len += sprintf(page + *len, "No SPC-2 Reservation holder\n"); | 1004 | len = sprintf(page, |
1018 | spin_unlock(&dev->dev_reservation_lock); | 1005 | "SPC-2 Reservation: %s Initiator: %s\n", |
1019 | return *len; | 1006 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), |
1007 | se_nacl->initiatorname); | ||
1008 | } else { | ||
1009 | len = sprintf(page, "No SPC-2 Reservation holder\n"); | ||
1020 | } | 1010 | } |
1021 | *len += sprintf(page + *len, "SPC-2 Reservation: %s Initiator: %s\n", | 1011 | return len; |
1022 | se_nacl->se_tpg->se_tpg_tfo->get_fabric_name(), | ||
1023 | se_nacl->initiatorname); | ||
1024 | spin_unlock(&dev->dev_reservation_lock); | ||
1025 | |||
1026 | return *len; | ||
1027 | } | 1012 | } |
1028 | 1013 | ||
1029 | static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev, | 1014 | static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev, |
1030 | char *page) | 1015 | char *page) |
1031 | { | 1016 | { |
1032 | ssize_t len = 0; | 1017 | int ret; |
1033 | 1018 | ||
1034 | switch (dev->t10_pr.res_type) { | 1019 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1035 | case SPC3_PERSISTENT_RESERVATIONS: | 1020 | return sprintf(page, "Passthrough\n"); |
1036 | target_core_dev_pr_show_spc3_res(dev, page, &len); | ||
1037 | break; | ||
1038 | case SPC2_RESERVATIONS: | ||
1039 | target_core_dev_pr_show_spc2_res(dev, page, &len); | ||
1040 | break; | ||
1041 | case SPC_PASSTHROUGH: | ||
1042 | len += sprintf(page+len, "Passthrough\n"); | ||
1043 | break; | ||
1044 | default: | ||
1045 | len += sprintf(page+len, "Unknown\n"); | ||
1046 | break; | ||
1047 | } | ||
1048 | 1021 | ||
1049 | return len; | 1022 | spin_lock(&dev->dev_reservation_lock); |
1023 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) | ||
1024 | ret = target_core_dev_pr_show_spc2_res(dev, page); | ||
1025 | else | ||
1026 | ret = target_core_dev_pr_show_spc3_res(dev, page); | ||
1027 | spin_unlock(&dev->dev_reservation_lock); | ||
1028 | return ret; | ||
1050 | } | 1029 | } |
1051 | 1030 | ||
1052 | SE_DEV_PR_ATTR_RO(res_holder); | 1031 | SE_DEV_PR_ATTR_RO(res_holder); |
@@ -1054,31 +1033,20 @@ SE_DEV_PR_ATTR_RO(res_holder); | |||
1054 | static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts( | 1033 | static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts( |
1055 | struct se_device *dev, char *page) | 1034 | struct se_device *dev, char *page) |
1056 | { | 1035 | { |
1057 | struct t10_pr_registration *pr_reg; | ||
1058 | ssize_t len = 0; | 1036 | ssize_t len = 0; |
1059 | 1037 | ||
1060 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1061 | return len; | ||
1062 | |||
1063 | spin_lock(&dev->dev_reservation_lock); | 1038 | spin_lock(&dev->dev_reservation_lock); |
1064 | pr_reg = dev->dev_pr_res_holder; | 1039 | if (!dev->dev_pr_res_holder) { |
1065 | if (!pr_reg) { | ||
1066 | len = sprintf(page, "No SPC-3 Reservation holder\n"); | 1040 | len = sprintf(page, "No SPC-3 Reservation holder\n"); |
1067 | spin_unlock(&dev->dev_reservation_lock); | 1041 | } else if (dev->dev_pr_res_holder->pr_reg_all_tg_pt) { |
1068 | return len; | ||
1069 | } | ||
1070 | /* | ||
1071 | * See All Target Ports (ALL_TG_PT) bit in spcr17, section 6.14.3 | ||
1072 | * Basic PERSISTENT RESERVER OUT parameter list, page 290 | ||
1073 | */ | ||
1074 | if (pr_reg->pr_reg_all_tg_pt) | ||
1075 | len = sprintf(page, "SPC-3 Reservation: All Target" | 1042 | len = sprintf(page, "SPC-3 Reservation: All Target" |
1076 | " Ports registration\n"); | 1043 | " Ports registration\n"); |
1077 | else | 1044 | } else { |
1078 | len = sprintf(page, "SPC-3 Reservation: Single" | 1045 | len = sprintf(page, "SPC-3 Reservation: Single" |
1079 | " Target Port registration\n"); | 1046 | " Target Port registration\n"); |
1080 | spin_unlock(&dev->dev_reservation_lock); | 1047 | } |
1081 | 1048 | ||
1049 | spin_unlock(&dev->dev_reservation_lock); | ||
1082 | return len; | 1050 | return len; |
1083 | } | 1051 | } |
1084 | 1052 | ||
@@ -1087,9 +1055,6 @@ SE_DEV_PR_ATTR_RO(res_pr_all_tgt_pts); | |||
1087 | static ssize_t target_core_dev_pr_show_attr_res_pr_generation( | 1055 | static ssize_t target_core_dev_pr_show_attr_res_pr_generation( |
1088 | struct se_device *dev, char *page) | 1056 | struct se_device *dev, char *page) |
1089 | { | 1057 | { |
1090 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1091 | return 0; | ||
1092 | |||
1093 | return sprintf(page, "0x%08x\n", dev->t10_pr.pr_generation); | 1058 | return sprintf(page, "0x%08x\n", dev->t10_pr.pr_generation); |
1094 | } | 1059 | } |
1095 | 1060 | ||
@@ -1108,16 +1073,13 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( | |||
1108 | struct target_core_fabric_ops *tfo; | 1073 | struct target_core_fabric_ops *tfo; |
1109 | ssize_t len = 0; | 1074 | ssize_t len = 0; |
1110 | 1075 | ||
1111 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1112 | return len; | ||
1113 | |||
1114 | spin_lock(&dev->dev_reservation_lock); | 1076 | spin_lock(&dev->dev_reservation_lock); |
1115 | pr_reg = dev->dev_pr_res_holder; | 1077 | pr_reg = dev->dev_pr_res_holder; |
1116 | if (!pr_reg) { | 1078 | if (!pr_reg) { |
1117 | len = sprintf(page, "No SPC-3 Reservation holder\n"); | 1079 | len = sprintf(page, "No SPC-3 Reservation holder\n"); |
1118 | spin_unlock(&dev->dev_reservation_lock); | 1080 | goto out_unlock; |
1119 | return len; | ||
1120 | } | 1081 | } |
1082 | |||
1121 | se_nacl = pr_reg->pr_reg_nacl; | 1083 | se_nacl = pr_reg->pr_reg_nacl; |
1122 | se_tpg = se_nacl->se_tpg; | 1084 | se_tpg = se_nacl->se_tpg; |
1123 | lun = pr_reg->pr_reg_tg_pt_lun; | 1085 | lun = pr_reg->pr_reg_tg_pt_lun; |
@@ -1131,8 +1093,9 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( | |||
1131 | " %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi, | 1093 | " %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi, |
1132 | tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg), | 1094 | tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg), |
1133 | tfo->get_fabric_name(), lun->unpacked_lun); | 1095 | tfo->get_fabric_name(), lun->unpacked_lun); |
1134 | spin_unlock(&dev->dev_reservation_lock); | ||
1135 | 1096 | ||
1097 | out_unlock: | ||
1098 | spin_unlock(&dev->dev_reservation_lock); | ||
1136 | return len; | 1099 | return len; |
1137 | } | 1100 | } |
1138 | 1101 | ||
@@ -1148,9 +1111,6 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | |||
1148 | ssize_t len = 0; | 1111 | ssize_t len = 0; |
1149 | int reg_count = 0, prf_isid; | 1112 | int reg_count = 0, prf_isid; |
1150 | 1113 | ||
1151 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1152 | return len; | ||
1153 | |||
1154 | len += sprintf(page+len, "SPC-3 PR Registrations:\n"); | 1114 | len += sprintf(page+len, "SPC-3 PR Registrations:\n"); |
1155 | 1115 | ||
1156 | spin_lock(&dev->t10_pr.registration_lock); | 1116 | spin_lock(&dev->t10_pr.registration_lock); |
@@ -1190,20 +1150,16 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_type( | |||
1190 | struct t10_pr_registration *pr_reg; | 1150 | struct t10_pr_registration *pr_reg; |
1191 | ssize_t len = 0; | 1151 | ssize_t len = 0; |
1192 | 1152 | ||
1193 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | ||
1194 | return len; | ||
1195 | |||
1196 | spin_lock(&dev->dev_reservation_lock); | 1153 | spin_lock(&dev->dev_reservation_lock); |
1197 | pr_reg = dev->dev_pr_res_holder; | 1154 | pr_reg = dev->dev_pr_res_holder; |
1198 | if (!pr_reg) { | 1155 | if (pr_reg) { |
1156 | len = sprintf(page, "SPC-3 Reservation Type: %s\n", | ||
1157 | core_scsi3_pr_dump_type(pr_reg->pr_res_type)); | ||
1158 | } else { | ||
1199 | len = sprintf(page, "No SPC-3 Reservation holder\n"); | 1159 | len = sprintf(page, "No SPC-3 Reservation holder\n"); |
1200 | spin_unlock(&dev->dev_reservation_lock); | ||
1201 | return len; | ||
1202 | } | 1160 | } |
1203 | len = sprintf(page, "SPC-3 Reservation Type: %s\n", | ||
1204 | core_scsi3_pr_dump_type(pr_reg->pr_res_type)); | ||
1205 | spin_unlock(&dev->dev_reservation_lock); | ||
1206 | 1161 | ||
1162 | spin_unlock(&dev->dev_reservation_lock); | ||
1207 | return len; | 1163 | return len; |
1208 | } | 1164 | } |
1209 | 1165 | ||
@@ -1212,24 +1168,12 @@ SE_DEV_PR_ATTR_RO(res_pr_type); | |||
1212 | static ssize_t target_core_dev_pr_show_attr_res_type( | 1168 | static ssize_t target_core_dev_pr_show_attr_res_type( |
1213 | struct se_device *dev, char *page) | 1169 | struct se_device *dev, char *page) |
1214 | { | 1170 | { |
1215 | ssize_t len = 0; | 1171 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1216 | 1172 | return sprintf(page, "SPC_PASSTHROUGH\n"); | |
1217 | switch (dev->t10_pr.res_type) { | 1173 | else if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) |
1218 | case SPC3_PERSISTENT_RESERVATIONS: | 1174 | return sprintf(page, "SPC2_RESERVATIONS\n"); |
1219 | len = sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n"); | 1175 | else |
1220 | break; | 1176 | return sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n"); |
1221 | case SPC2_RESERVATIONS: | ||
1222 | len = sprintf(page, "SPC2_RESERVATIONS\n"); | ||
1223 | break; | ||
1224 | case SPC_PASSTHROUGH: | ||
1225 | len = sprintf(page, "SPC_PASSTHROUGH\n"); | ||
1226 | break; | ||
1227 | default: | ||
1228 | len = sprintf(page, "UNKNOWN\n"); | ||
1229 | break; | ||
1230 | } | ||
1231 | |||
1232 | return len; | ||
1233 | } | 1177 | } |
1234 | 1178 | ||
1235 | SE_DEV_PR_ATTR_RO(res_type); | 1179 | SE_DEV_PR_ATTR_RO(res_type); |
@@ -1237,7 +1181,7 @@ SE_DEV_PR_ATTR_RO(res_type); | |||
1237 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_active( | 1181 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_active( |
1238 | struct se_device *dev, char *page) | 1182 | struct se_device *dev, char *page) |
1239 | { | 1183 | { |
1240 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | 1184 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1241 | return 0; | 1185 | return 0; |
1242 | 1186 | ||
1243 | return sprintf(page, "APTPL Bit Status: %s\n", | 1187 | return sprintf(page, "APTPL Bit Status: %s\n", |
@@ -1252,7 +1196,7 @@ SE_DEV_PR_ATTR_RO(res_aptpl_active); | |||
1252 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata( | 1196 | static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata( |
1253 | struct se_device *dev, char *page) | 1197 | struct se_device *dev, char *page) |
1254 | { | 1198 | { |
1255 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | 1199 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1256 | return 0; | 1200 | return 0; |
1257 | 1201 | ||
1258 | return sprintf(page, "Ready to process PR APTPL metadata..\n"); | 1202 | return sprintf(page, "Ready to process PR APTPL metadata..\n"); |
@@ -1299,7 +1243,9 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( | |||
1299 | u16 port_rpti = 0, tpgt = 0; | 1243 | u16 port_rpti = 0, tpgt = 0; |
1300 | u8 type = 0, scope; | 1244 | u8 type = 0, scope; |
1301 | 1245 | ||
1302 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | 1246 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
1247 | return 0; | ||
1248 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) | ||
1303 | return 0; | 1249 | return 0; |
1304 | 1250 | ||
1305 | if (dev->export_count) { | 1251 | if (dev->export_count) { |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 6a27e7fd33fb..4ae1d3913821 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1398,7 +1398,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
1398 | dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; | 1398 | dev->dev_attrib.emulate_tas = DA_EMULATE_TAS; |
1399 | dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; | 1399 | dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU; |
1400 | dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; | 1400 | dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS; |
1401 | dev->dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS; | ||
1402 | dev->dev_attrib.emulate_alua = DA_EMULATE_ALUA; | 1401 | dev->dev_attrib.emulate_alua = DA_EMULATE_ALUA; |
1403 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; | 1402 | dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS; |
1404 | dev->dev_attrib.is_nonrot = DA_IS_NONROT; | 1403 | dev->dev_attrib.is_nonrot = DA_IS_NONROT; |
@@ -1447,8 +1446,6 @@ int target_configure_device(struct se_device *dev) | |||
1447 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); | 1446 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); |
1448 | dev->creation_time = get_jiffies_64(); | 1447 | dev->creation_time = get_jiffies_64(); |
1449 | 1448 | ||
1450 | core_setup_reservations(dev); | ||
1451 | |||
1452 | ret = core_setup_alua(dev); | 1449 | ret = core_setup_alua(dev); |
1453 | if (ret) | 1450 | if (ret) |
1454 | goto out; | 1451 | goto out; |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 2b289891672f..f561a08ff8e5 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -68,49 +68,32 @@ int core_pr_dump_initiator_port( | |||
68 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, | 68 | static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, |
69 | struct t10_pr_registration *, int); | 69 | struct t10_pr_registration *, int); |
70 | 70 | ||
71 | static int core_scsi2_reservation_seq_non_holder( | 71 | static int target_scsi2_reservation_check(struct se_cmd *cmd) |
72 | struct se_cmd *cmd, | ||
73 | unsigned char *cdb, | ||
74 | u32 pr_reg_type) | ||
75 | { | 72 | { |
76 | switch (cdb[0]) { | 73 | struct se_device *dev = cmd->se_dev; |
74 | struct se_session *sess = cmd->se_sess; | ||
75 | |||
76 | switch (cmd->t_task_cdb[0]) { | ||
77 | case INQUIRY: | 77 | case INQUIRY: |
78 | case RELEASE: | 78 | case RELEASE: |
79 | case RELEASE_10: | 79 | case RELEASE_10: |
80 | return 0; | 80 | return 0; |
81 | default: | 81 | default: |
82 | return 1; | 82 | break; |
83 | } | 83 | } |
84 | 84 | ||
85 | return 1; | 85 | if (!dev->dev_reserved_node_acl || !sess) |
86 | } | ||
87 | |||
88 | static int core_scsi2_reservation_check(struct se_cmd *cmd, u32 *pr_reg_type) | ||
89 | { | ||
90 | struct se_device *dev = cmd->se_dev; | ||
91 | struct se_session *sess = cmd->se_sess; | ||
92 | int ret; | ||
93 | |||
94 | if (!sess) | ||
95 | return 0; | 86 | return 0; |
96 | 87 | ||
97 | spin_lock(&dev->dev_reservation_lock); | 88 | if (dev->dev_reserved_node_acl != sess->se_node_acl) |
98 | if (!dev->dev_reserved_node_acl || !sess) { | 89 | return -EBUSY; |
99 | spin_unlock(&dev->dev_reservation_lock); | 90 | |
100 | return 0; | 91 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) { |
101 | } | 92 | if (dev->dev_res_bin_isid != sess->sess_bin_isid) |
102 | if (dev->dev_reserved_node_acl != sess->se_node_acl) { | 93 | return -EBUSY; |
103 | spin_unlock(&dev->dev_reservation_lock); | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | if (!(dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID)) { | ||
107 | spin_unlock(&dev->dev_reservation_lock); | ||
108 | return 0; | ||
109 | } | 94 | } |
110 | ret = (dev->dev_res_bin_isid == sess->sess_bin_isid) ? 0 : -EINVAL; | ||
111 | spin_unlock(&dev->dev_reservation_lock); | ||
112 | 95 | ||
113 | return ret; | 96 | return 0; |
114 | } | 97 | } |
115 | 98 | ||
116 | static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, | 99 | static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, |
@@ -123,12 +106,8 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) | |||
123 | struct se_device *dev = cmd->se_dev; | 106 | struct se_device *dev = cmd->se_dev; |
124 | struct t10_pr_registration *pr_reg; | 107 | struct t10_pr_registration *pr_reg; |
125 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 108 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
126 | int crh = (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS); | ||
127 | int conflict = 0; | 109 | int conflict = 0; |
128 | 110 | ||
129 | if (!crh) | ||
130 | return -EINVAL; | ||
131 | |||
132 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | 111 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
133 | se_sess); | 112 | se_sess); |
134 | if (pr_reg) { | 113 | if (pr_reg) { |
@@ -319,9 +298,9 @@ out: | |||
319 | */ | 298 | */ |
320 | static int core_scsi3_pr_seq_non_holder( | 299 | static int core_scsi3_pr_seq_non_holder( |
321 | struct se_cmd *cmd, | 300 | struct se_cmd *cmd, |
322 | unsigned char *cdb, | ||
323 | u32 pr_reg_type) | 301 | u32 pr_reg_type) |
324 | { | 302 | { |
303 | unsigned char *cdb = cmd->t_task_cdb; | ||
325 | struct se_dev_entry *se_deve; | 304 | struct se_dev_entry *se_deve; |
326 | struct se_session *se_sess = cmd->se_sess; | 305 | struct se_session *se_sess = cmd->se_sess; |
327 | int other_cdb = 0, ignore_reg; | 306 | int other_cdb = 0, ignore_reg; |
@@ -330,17 +309,11 @@ static int core_scsi3_pr_seq_non_holder( | |||
330 | int we = 0; /* Write Exclusive */ | 309 | int we = 0; /* Write Exclusive */ |
331 | int legacy = 0; /* Act like a legacy device and return | 310 | int legacy = 0; /* Act like a legacy device and return |
332 | * RESERVATION CONFLICT on some CDBs */ | 311 | * RESERVATION CONFLICT on some CDBs */ |
333 | /* | ||
334 | * A legacy SPC-2 reservation is being held. | ||
335 | */ | ||
336 | if (cmd->se_dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) | ||
337 | return core_scsi2_reservation_seq_non_holder(cmd, | ||
338 | cdb, pr_reg_type); | ||
339 | 312 | ||
340 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 313 | se_deve = se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
341 | /* | 314 | /* |
342 | * Determine if the registration should be ignored due to | 315 | * Determine if the registration should be ignored due to |
343 | * non-matching ISIDs in core_scsi3_pr_reservation_check(). | 316 | * non-matching ISIDs in target_scsi3_pr_reservation_check(). |
344 | */ | 317 | */ |
345 | ignore_reg = (pr_reg_type & 0x80000000); | 318 | ignore_reg = (pr_reg_type & 0x80000000); |
346 | if (ignore_reg) | 319 | if (ignore_reg) |
@@ -563,6 +536,36 @@ static int core_scsi3_pr_seq_non_holder( | |||
563 | return 1; /* Conflict by default */ | 536 | return 1; /* Conflict by default */ |
564 | } | 537 | } |
565 | 538 | ||
539 | static int target_scsi3_pr_reservation_check(struct se_cmd *cmd) | ||
540 | { | ||
541 | struct se_device *dev = cmd->se_dev; | ||
542 | struct se_session *sess = cmd->se_sess; | ||
543 | u32 pr_reg_type; | ||
544 | |||
545 | if (!dev->dev_pr_res_holder) | ||
546 | return 0; | ||
547 | |||
548 | pr_reg_type = dev->dev_pr_res_holder->pr_res_type; | ||
549 | cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key; | ||
550 | if (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl) | ||
551 | goto check_nonholder; | ||
552 | |||
553 | if (dev->dev_pr_res_holder->isid_present_at_reg) { | ||
554 | if (dev->dev_pr_res_holder->pr_reg_bin_isid != | ||
555 | sess->sess_bin_isid) { | ||
556 | pr_reg_type |= 0x80000000; | ||
557 | goto check_nonholder; | ||
558 | } | ||
559 | } | ||
560 | |||
561 | return 0; | ||
562 | |||
563 | check_nonholder: | ||
564 | if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type)) | ||
565 | return -EBUSY; | ||
566 | return 0; | ||
567 | } | ||
568 | |||
566 | static u32 core_scsi3_pr_generation(struct se_device *dev) | 569 | static u32 core_scsi3_pr_generation(struct se_device *dev) |
567 | { | 570 | { |
568 | u32 prg; | 571 | u32 prg; |
@@ -583,50 +586,6 @@ static u32 core_scsi3_pr_generation(struct se_device *dev) | |||
583 | return prg; | 586 | return prg; |
584 | } | 587 | } |
585 | 588 | ||
586 | static int core_scsi3_pr_reservation_check( | ||
587 | struct se_cmd *cmd, | ||
588 | u32 *pr_reg_type) | ||
589 | { | ||
590 | struct se_device *dev = cmd->se_dev; | ||
591 | struct se_session *sess = cmd->se_sess; | ||
592 | int ret; | ||
593 | |||
594 | if (!sess) | ||
595 | return 0; | ||
596 | /* | ||
597 | * A legacy SPC-2 reservation is being held. | ||
598 | */ | ||
599 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) | ||
600 | return core_scsi2_reservation_check(cmd, pr_reg_type); | ||
601 | |||
602 | spin_lock(&dev->dev_reservation_lock); | ||
603 | if (!dev->dev_pr_res_holder) { | ||
604 | spin_unlock(&dev->dev_reservation_lock); | ||
605 | return 0; | ||
606 | } | ||
607 | *pr_reg_type = dev->dev_pr_res_holder->pr_res_type; | ||
608 | cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key; | ||
609 | if (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl) { | ||
610 | spin_unlock(&dev->dev_reservation_lock); | ||
611 | return -EINVAL; | ||
612 | } | ||
613 | if (!dev->dev_pr_res_holder->isid_present_at_reg) { | ||
614 | spin_unlock(&dev->dev_reservation_lock); | ||
615 | return 0; | ||
616 | } | ||
617 | ret = (dev->dev_pr_res_holder->pr_reg_bin_isid == | ||
618 | sess->sess_bin_isid) ? 0 : -EINVAL; | ||
619 | /* | ||
620 | * Use bit in *pr_reg_type to notify ISID mismatch in | ||
621 | * core_scsi3_pr_seq_non_holder(). | ||
622 | */ | ||
623 | if (ret != 0) | ||
624 | *pr_reg_type |= 0x80000000; | ||
625 | spin_unlock(&dev->dev_reservation_lock); | ||
626 | |||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | static struct t10_pr_registration *__core_scsi3_do_alloc_registration( | 589 | static struct t10_pr_registration *__core_scsi3_do_alloc_registration( |
631 | struct se_device *dev, | 590 | struct se_device *dev, |
632 | struct se_node_acl *nacl, | 591 | struct se_node_acl *nacl, |
@@ -998,7 +957,7 @@ int core_scsi3_check_aptpl_registration( | |||
998 | struct se_node_acl *nacl = lun_acl->se_lun_nacl; | 957 | struct se_node_acl *nacl = lun_acl->se_lun_nacl; |
999 | struct se_dev_entry *deve = nacl->device_list[lun_acl->mapped_lun]; | 958 | struct se_dev_entry *deve = nacl->device_list[lun_acl->mapped_lun]; |
1000 | 959 | ||
1001 | if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS) | 960 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) |
1002 | return 0; | 961 | return 0; |
1003 | 962 | ||
1004 | return __core_scsi3_check_aptpl_registration(dev, tpg, lun, | 963 | return __core_scsi3_check_aptpl_registration(dev, tpg, lun, |
@@ -4343,49 +4302,24 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd) | |||
4343 | return ret; | 4302 | return ret; |
4344 | } | 4303 | } |
4345 | 4304 | ||
4346 | static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) | 4305 | int target_check_reservation(struct se_cmd *cmd) |
4347 | { | 4306 | { |
4348 | return 0; | 4307 | struct se_device *dev = cmd->se_dev; |
4349 | } | 4308 | int ret; |
4350 | 4309 | ||
4351 | static int core_pt_seq_non_holder( | 4310 | if (!cmd->se_sess) |
4352 | struct se_cmd *cmd, | 4311 | return 0; |
4353 | unsigned char *cdb, | 4312 | if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) |
4354 | u32 pr_reg_type) | 4313 | return 0; |
4355 | { | 4314 | if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) |
4356 | return 0; | 4315 | return 0; |
4357 | } | ||
4358 | 4316 | ||
4359 | void core_setup_reservations(struct se_device *dev) | 4317 | spin_lock(&dev->dev_reservation_lock); |
4360 | { | 4318 | if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) |
4361 | struct t10_reservation *rest = &dev->t10_pr; | 4319 | ret = target_scsi2_reservation_check(cmd); |
4320 | else | ||
4321 | ret = target_scsi3_pr_reservation_check(cmd); | ||
4322 | spin_unlock(&dev->dev_reservation_lock); | ||
4362 | 4323 | ||
4363 | /* | 4324 | return ret; |
4364 | * If this device is from Target_Core_Mod/pSCSI, use the reservations | ||
4365 | * of the Underlying SCSI hardware. In Linux/SCSI terms, this can | ||
4366 | * cause a problem because libata and some SATA RAID HBAs appear | ||
4367 | * under Linux/SCSI, but to emulate reservations themselves. | ||
4368 | */ | ||
4369 | if ((dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) || | ||
4370 | (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV && | ||
4371 | !dev->dev_attrib.emulate_reservations)) { | ||
4372 | rest->res_type = SPC_PASSTHROUGH; | ||
4373 | rest->pr_ops.t10_reservation_check = &core_pt_reservation_check; | ||
4374 | rest->pr_ops.t10_seq_non_holder = &core_pt_seq_non_holder; | ||
4375 | pr_debug("%s: Using SPC_PASSTHROUGH, no reservation" | ||
4376 | " emulation\n", dev->transport->name); | ||
4377 | } else if (dev->transport->get_device_rev(dev) >= SCSI_3) { | ||
4378 | rest->res_type = SPC3_PERSISTENT_RESERVATIONS; | ||
4379 | rest->pr_ops.t10_reservation_check = &core_scsi3_pr_reservation_check; | ||
4380 | rest->pr_ops.t10_seq_non_holder = &core_scsi3_pr_seq_non_holder; | ||
4381 | pr_debug("%s: Using SPC3_PERSISTENT_RESERVATIONS" | ||
4382 | " emulation\n", dev->transport->name); | ||
4383 | } else { | ||
4384 | rest->res_type = SPC2_RESERVATIONS; | ||
4385 | rest->pr_ops.t10_reservation_check = &core_scsi2_reservation_check; | ||
4386 | rest->pr_ops.t10_seq_non_holder = | ||
4387 | &core_scsi2_reservation_seq_non_holder; | ||
4388 | pr_debug("%s: Using SPC2_RESERVATIONS emulation\n", | ||
4389 | dev->transport->name); | ||
4390 | } | ||
4391 | } | 4325 | } |
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h index 78451437d2c2..7616f2690ca0 100644 --- a/drivers/target/target_core_pr.h +++ b/drivers/target/target_core_pr.h | |||
@@ -63,6 +63,6 @@ extern unsigned char *core_scsi3_pr_dump_type(int); | |||
63 | 63 | ||
64 | extern int target_scsi3_emulate_pr_in(struct se_cmd *); | 64 | extern int target_scsi3_emulate_pr_in(struct se_cmd *); |
65 | extern int target_scsi3_emulate_pr_out(struct se_cmd *); | 65 | extern int target_scsi3_emulate_pr_out(struct se_cmd *); |
66 | extern void core_setup_reservations(struct se_device *); | 66 | extern int target_check_reservation(struct se_cmd *cmd); |
67 | 67 | ||
68 | #endif /* TARGET_CORE_PR_H */ | 68 | #endif /* TARGET_CORE_PR_H */ |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 8ca62631ec7f..862e4347f68f 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -1003,14 +1003,12 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1003 | *size = (cdb[7] << 8) + cdb[8]; | 1003 | *size = (cdb[7] << 8) + cdb[8]; |
1004 | break; | 1004 | break; |
1005 | case PERSISTENT_RESERVE_IN: | 1005 | case PERSISTENT_RESERVE_IN: |
1006 | if (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) | ||
1007 | cmd->execute_cmd = target_scsi3_emulate_pr_in; | ||
1008 | *size = (cdb[7] << 8) + cdb[8]; | 1006 | *size = (cdb[7] << 8) + cdb[8]; |
1007 | cmd->execute_cmd = target_scsi3_emulate_pr_in; | ||
1009 | break; | 1008 | break; |
1010 | case PERSISTENT_RESERVE_OUT: | 1009 | case PERSISTENT_RESERVE_OUT: |
1011 | if (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS) | ||
1012 | cmd->execute_cmd = target_scsi3_emulate_pr_out; | ||
1013 | *size = (cdb[7] << 8) + cdb[8]; | 1010 | *size = (cdb[7] << 8) + cdb[8]; |
1011 | cmd->execute_cmd = target_scsi3_emulate_pr_out; | ||
1014 | break; | 1012 | break; |
1015 | case RELEASE: | 1013 | case RELEASE: |
1016 | case RELEASE_10: | 1014 | case RELEASE_10: |
@@ -1019,8 +1017,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1019 | else | 1017 | else |
1020 | *size = cmd->data_length; | 1018 | *size = cmd->data_length; |
1021 | 1019 | ||
1022 | if (dev->t10_pr.res_type != SPC_PASSTHROUGH) | 1020 | cmd->execute_cmd = target_scsi2_reservation_release; |
1023 | cmd->execute_cmd = target_scsi2_reservation_release; | ||
1024 | break; | 1021 | break; |
1025 | case RESERVE: | 1022 | case RESERVE: |
1026 | case RESERVE_10: | 1023 | case RESERVE_10: |
@@ -1033,15 +1030,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1033 | else | 1030 | else |
1034 | *size = cmd->data_length; | 1031 | *size = cmd->data_length; |
1035 | 1032 | ||
1036 | /* | 1033 | cmd->execute_cmd = target_scsi2_reservation_reserve; |
1037 | * Setup the legacy emulated handler for SPC-2 and | ||
1038 | * >= SPC-3 compatible reservation handling (CRH=1) | ||
1039 | * Otherwise, we assume the underlying SCSI logic is | ||
1040 | * is running in SPC_PASSTHROUGH, and wants reservations | ||
1041 | * emulation disabled. | ||
1042 | */ | ||
1043 | if (dev->t10_pr.res_type != SPC_PASSTHROUGH) | ||
1044 | cmd->execute_cmd = target_scsi2_reservation_reserve; | ||
1045 | break; | 1034 | break; |
1046 | case REQUEST_SENSE: | 1035 | case REQUEST_SENSE: |
1047 | *size = cdb[4]; | 1036 | *size = cdb[4]; |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 757e3777ce79..e996bdf480cf 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1103,7 +1103,6 @@ int target_setup_cmd_from_cdb( | |||
1103 | unsigned char *cdb) | 1103 | unsigned char *cdb) |
1104 | { | 1104 | { |
1105 | struct se_device *dev = cmd->se_dev; | 1105 | struct se_device *dev = cmd->se_dev; |
1106 | u32 pr_reg_type = 0; | ||
1107 | u8 alua_ascq = 0; | 1106 | u8 alua_ascq = 0; |
1108 | unsigned long flags; | 1107 | unsigned long flags; |
1109 | int ret; | 1108 | int ret; |
@@ -1180,20 +1179,13 @@ int target_setup_cmd_from_cdb( | |||
1180 | /* | 1179 | /* |
1181 | * Check status for SPC-3 Persistent Reservations | 1180 | * Check status for SPC-3 Persistent Reservations |
1182 | */ | 1181 | */ |
1183 | if (dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) { | 1182 | ret = target_check_reservation(cmd); |
1184 | if (dev->t10_pr.pr_ops.t10_seq_non_holder( | 1183 | if (ret) { |
1185 | cmd, cdb, pr_reg_type) != 0) { | 1184 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
1186 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 1185 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; |
1187 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | 1186 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; |
1188 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | 1187 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
1189 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 1188 | return ret; |
1190 | return -EBUSY; | ||
1191 | } | ||
1192 | /* | ||
1193 | * This means the CDB is allowed for the SCSI Initiator port | ||
1194 | * when said port is *NOT* holding the legacy SPC-2 or | ||
1195 | * SPC-3 Persistent Reservation. | ||
1196 | */ | ||
1197 | } | 1189 | } |
1198 | 1190 | ||
1199 | ret = dev->transport->parse_cdb(cmd); | 1191 | ret = dev->transport->parse_cdb(cmd); |