aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-10-10 17:37:15 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-06 23:55:45 -0500
commitd977f4377fbc396b888e12fdb3b13118b09ca7db (patch)
treef3de282b1df951ec599908e24590dbcbac5b9047 /drivers/target
parent019c4ca621488739b1bfb7597a14ac7f0cbcc908 (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.c158
-rw-r--r--drivers/target/target_core_device.c3
-rw-r--r--drivers/target/target_core_pr.c192
-rw-r--r--drivers/target/target_core_pr.h2
-rw-r--r--drivers/target/target_core_spc.c19
-rw-r--r--drivers/target/target_core_transport.c22
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/* 973static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev,
974 * res_holder 974 char *page)
975 */
976static 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
1007static ssize_t target_core_dev_pr_show_spc2_res( 996static 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
1029static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev, 1014static 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
1052SE_DEV_PR_ATTR_RO(res_holder); 1031SE_DEV_PR_ATTR_RO(res_holder);
@@ -1054,31 +1033,20 @@ SE_DEV_PR_ATTR_RO(res_holder);
1054static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts( 1033static 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);
1087static ssize_t target_core_dev_pr_show_attr_res_pr_generation( 1055static 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
1097out_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);
1212static ssize_t target_core_dev_pr_show_attr_res_type( 1168static 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
1235SE_DEV_PR_ATTR_RO(res_type); 1179SE_DEV_PR_ATTR_RO(res_type);
@@ -1237,7 +1181,7 @@ SE_DEV_PR_ATTR_RO(res_type);
1237static ssize_t target_core_dev_pr_show_attr_res_aptpl_active( 1181static 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);
1252static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata( 1196static 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(
68static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, 68static 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
71static int core_scsi2_reservation_seq_non_holder( 71static 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
88static 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
116static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, 99static 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 */
320static int core_scsi3_pr_seq_non_holder( 299static 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
539static 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
563check_nonholder:
564 if (core_scsi3_pr_seq_non_holder(cmd, pr_reg_type))
565 return -EBUSY;
566 return 0;
567}
568
566static u32 core_scsi3_pr_generation(struct se_device *dev) 569static 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
586static 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
630static struct t10_pr_registration *__core_scsi3_do_alloc_registration( 589static 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
4346static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type) 4305int 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
4351static 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
4359void 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
64extern int target_scsi3_emulate_pr_in(struct se_cmd *); 64extern int target_scsi3_emulate_pr_in(struct se_cmd *);
65extern int target_scsi3_emulate_pr_out(struct se_cmd *); 65extern int target_scsi3_emulate_pr_out(struct se_cmd *);
66extern void core_setup_reservations(struct se_device *); 66extern 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);