blob: b7c779389eea6820c34c5f9d6a6dafc98638c932 [file] [log] [blame]
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001/*******************************************************************************
2 * Filename: target_core_pr.c
3 *
4 * This file contains SPC-3 compliant persistent reservations and
5 * legacy SPC-2 reservations with compatible reservation handling (CRH=1)
6 *
7 * Copyright (c) 2009, 2010 Rising Tide Systems
8 * Copyright (c) 2009, 2010 Linux-iSCSI.org
9 *
10 * Nicholas A. Bellinger <nab@kernel.org>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 *
26 ******************************************************************************/
27
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080028#include <linux/slab.h>
29#include <linux/spinlock.h>
30#include <linux/list.h>
31#include <scsi/scsi.h>
32#include <scsi/scsi_cmnd.h>
33#include <asm/unaligned.h>
34
35#include <target/target_core_base.h>
Christoph Hellwigc4795fb2011-11-16 09:46:48 -050036#include <target/target_core_backend.h>
37#include <target/target_core_fabric.h>
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080038#include <target/target_core_configfs.h>
39
Christoph Hellwige26d99a2011-11-14 12:30:30 -050040#include "target_core_internal.h"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080041#include "target_core_pr.h"
42#include "target_core_ua.h"
43
44/*
45 * Used for Specify Initiator Ports Capable Bit (SPEC_I_PT)
46 */
47struct pr_transport_id_holder {
48 int dest_local_nexus;
49 struct t10_pr_registration *dest_pr_reg;
50 struct se_portal_group *dest_tpg;
51 struct se_node_acl *dest_node_acl;
52 struct se_dev_entry *dest_se_deve;
53 struct list_head dest_list;
54};
55
56int core_pr_dump_initiator_port(
57 struct t10_pr_registration *pr_reg,
58 char *buf,
59 u32 size)
60{
Andy Grover6708bb22011-06-08 10:36:43 -070061 if (!pr_reg->isid_present_at_reg)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080062 return 0;
63
64 snprintf(buf, size, ",i,0x%s", &pr_reg->pr_reg_isid[0]);
65 return 1;
66}
67
68static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *,
69 struct t10_pr_registration *, int);
70
71static int core_scsi2_reservation_seq_non_holder(
72 struct se_cmd *cmd,
73 unsigned char *cdb,
74 u32 pr_reg_type)
75{
76 switch (cdb[0]) {
77 case INQUIRY:
78 case RELEASE:
79 case RELEASE_10:
80 return 0;
81 default:
82 return 1;
83 }
84
85 return 1;
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
Andy Grover6708bb22011-06-08 10:36:43 -070094 if (!sess)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -080095 return 0;
96
97 spin_lock(&dev->dev_reservation_lock);
98 if (!dev->dev_reserved_node_acl || !sess) {
99 spin_unlock(&dev->dev_reservation_lock);
100 return 0;
101 }
102 if (dev->dev_reserved_node_acl != sess->se_node_acl) {
103 spin_unlock(&dev->dev_reservation_lock);
Andy Grovere3d6f902011-07-19 08:55:10 +0000104 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800105 }
106 if (!(dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID)) {
107 spin_unlock(&dev->dev_reservation_lock);
108 return 0;
109 }
Andy Grovere3d6f902011-07-19 08:55:10 +0000110 ret = (dev->dev_res_bin_isid == sess->sess_bin_isid) ? 0 : -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800111 spin_unlock(&dev->dev_reservation_lock);
112
113 return ret;
114}
115
Christoph Hellwigeacac002011-11-03 17:50:40 -0400116static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *,
117 struct se_node_acl *, struct se_session *);
118static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
119
120static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret)
121{
122 struct se_session *se_sess = cmd->se_sess;
123 struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
124 struct t10_pr_registration *pr_reg;
125 struct t10_reservation *pr_tmpl = &su_dev->t10_pr;
126 int crh = (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS);
127 int conflict = 0;
128
129 if (!crh)
130 return false;
131
132 pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
133 se_sess);
134 if (pr_reg) {
135 /*
136 * From spc4r17 5.7.3 Exceptions to SPC-2 RESERVE and RELEASE
137 * behavior
138 *
139 * A RESERVE(6) or RESERVE(10) command shall complete with GOOD
140 * status, but no reservation shall be established and the
141 * persistent reservation shall not be changed, if the command
142 * is received from a) and b) below.
143 *
144 * A RELEASE(6) or RELEASE(10) command shall complete with GOOD
145 * status, but the persistent reservation shall not be released,
146 * if the command is received from a) and b)
147 *
148 * a) An I_T nexus that is a persistent reservation holder; or
149 * b) An I_T nexus that is registered if a registrants only or
150 * all registrants type persistent reservation is present.
151 *
152 * In all other cases, a RESERVE(6) command, RESERVE(10) command,
153 * RELEASE(6) command, or RELEASE(10) command shall be processed
154 * as defined in SPC-2.
155 */
156 if (pr_reg->pr_res_holder) {
157 core_scsi3_put_pr_reg(pr_reg);
158 *ret = 0;
159 return false;
160 }
161 if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
162 (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) ||
163 (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
164 (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
165 core_scsi3_put_pr_reg(pr_reg);
166 *ret = 0;
167 return true;
168 }
169 core_scsi3_put_pr_reg(pr_reg);
170 conflict = 1;
171 } else {
172 /*
173 * Following spc2r20 5.5.1 Reservations overview:
174 *
175 * If a logical unit has executed a PERSISTENT RESERVE OUT
176 * command with the REGISTER or the REGISTER AND IGNORE
177 * EXISTING KEY service action and is still registered by any
178 * initiator, all RESERVE commands and all RELEASE commands
179 * regardless of initiator shall conflict and shall terminate
180 * with a RESERVATION CONFLICT status.
181 */
182 spin_lock(&pr_tmpl->registration_lock);
183 conflict = (list_empty(&pr_tmpl->registration_list)) ? 0 : 1;
184 spin_unlock(&pr_tmpl->registration_lock);
185 }
186
187 if (conflict) {
188 pr_err("Received legacy SPC-2 RESERVE/RELEASE"
189 " while active SPC-3 registrations exist,"
190 " returning RESERVATION_CONFLICT\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -0700191 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
Christoph Hellwigeacac002011-11-03 17:50:40 -0400192 return true;
193 }
194
195 return false;
196}
197
Christoph Hellwige76a35d2011-11-03 17:50:42 -0400198int target_scsi2_reservation_release(struct se_task *task)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800199{
Christoph Hellwige76a35d2011-11-03 17:50:42 -0400200 struct se_cmd *cmd = task->task_se_cmd;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800201 struct se_device *dev = cmd->se_dev;
202 struct se_session *sess = cmd->se_sess;
203 struct se_portal_group *tpg = sess->se_tpg;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400204 int ret = 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800205
Andy Grover6708bb22011-06-08 10:36:43 -0700206 if (!sess || !tpg)
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400207 goto out;
Christoph Hellwigeacac002011-11-03 17:50:40 -0400208 if (target_check_scsi2_reservation_conflict(cmd, &ret))
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400209 goto out;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800210
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400211 ret = 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800212 spin_lock(&dev->dev_reservation_lock);
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400213 if (!dev->dev_reserved_node_acl || !sess)
214 goto out_unlock;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800215
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400216 if (dev->dev_reserved_node_acl != sess->se_node_acl)
217 goto out_unlock;
218
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800219 dev->dev_reserved_node_acl = NULL;
220 dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
221 if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
222 dev->dev_res_bin_isid = 0;
223 dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID;
224 }
Andy Grover6708bb22011-06-08 10:36:43 -0700225 pr_debug("SCSI-2 Released reservation for %s LUN: %u ->"
Andy Grovere3d6f902011-07-19 08:55:10 +0000226 " MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
227 cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800228 sess->se_node_acl->initiatorname);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800229
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400230out_unlock:
231 spin_unlock(&dev->dev_reservation_lock);
232out:
233 if (!ret) {
234 task->task_scsi_status = GOOD;
235 transport_complete_task(task, 1);
236 }
237 return ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800238}
239
Christoph Hellwige76a35d2011-11-03 17:50:42 -0400240int target_scsi2_reservation_reserve(struct se_task *task)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800241{
Christoph Hellwige76a35d2011-11-03 17:50:42 -0400242 struct se_cmd *cmd = task->task_se_cmd;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800243 struct se_device *dev = cmd->se_dev;
244 struct se_session *sess = cmd->se_sess;
245 struct se_portal_group *tpg = sess->se_tpg;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400246 int ret = 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800247
Andy Grovera1d8b492011-05-02 17:12:10 -0700248 if ((cmd->t_task_cdb[1] & 0x01) &&
249 (cmd->t_task_cdb[1] & 0x02)) {
Andy Grover6708bb22011-06-08 10:36:43 -0700250 pr_err("LongIO and Obselete Bits set, returning"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800251 " ILLEGAL_REQUEST\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -0700252 cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
253 ret = -EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400254 goto out;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800255 }
256 /*
257 * This is currently the case for target_core_mod passthrough struct se_cmd
258 * ops
259 */
Andy Grover6708bb22011-06-08 10:36:43 -0700260 if (!sess || !tpg)
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400261 goto out;
Christoph Hellwigeacac002011-11-03 17:50:40 -0400262 if (target_check_scsi2_reservation_conflict(cmd, &ret))
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400263 goto out;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800264
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400265 ret = 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800266 spin_lock(&dev->dev_reservation_lock);
267 if (dev->dev_reserved_node_acl &&
268 (dev->dev_reserved_node_acl != sess->se_node_acl)) {
Andy Grover6708bb22011-06-08 10:36:43 -0700269 pr_err("SCSI-2 RESERVATION CONFLIFT for %s fabric\n",
Andy Grovere3d6f902011-07-19 08:55:10 +0000270 tpg->se_tpg_tfo->get_fabric_name());
Andy Grover6708bb22011-06-08 10:36:43 -0700271 pr_err("Original reserver LUN: %u %s\n",
Andy Grovere3d6f902011-07-19 08:55:10 +0000272 cmd->se_lun->unpacked_lun,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800273 dev->dev_reserved_node_acl->initiatorname);
Andy Grover6708bb22011-06-08 10:36:43 -0700274 pr_err("Current attempt - LUN: %u -> MAPPED LUN: %u"
Andy Grovere3d6f902011-07-19 08:55:10 +0000275 " from %s \n", cmd->se_lun->unpacked_lun,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800276 cmd->se_deve->mapped_lun,
277 sess->se_node_acl->initiatorname);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -0700278 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
279 ret = -EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400280 goto out_unlock;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800281 }
282
283 dev->dev_reserved_node_acl = sess->se_node_acl;
284 dev->dev_flags |= DF_SPC2_RESERVATIONS;
285 if (sess->sess_bin_isid != 0) {
286 dev->dev_res_bin_isid = sess->sess_bin_isid;
287 dev->dev_flags |= DF_SPC2_RESERVATIONS_WITH_ISID;
288 }
Andy Grover6708bb22011-06-08 10:36:43 -0700289 pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u"
Andy Grovere3d6f902011-07-19 08:55:10 +0000290 " for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
291 cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800292 sess->se_node_acl->initiatorname);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800293
Christoph Hellwigd29a5b62011-11-03 17:50:44 -0400294out_unlock:
295 spin_unlock(&dev->dev_reservation_lock);
296out:
297 if (!ret) {
298 task->task_scsi_status = GOOD;
299 transport_complete_task(task, 1);
300 }
301 return ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800302}
303
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800304
305/*
306 * Begin SPC-3/SPC-4 Persistent Reservations emulation support
307 *
308 * This function is called by those initiator ports who are *NOT*
309 * the active PR reservation holder when a reservation is present.
310 */
311static int core_scsi3_pr_seq_non_holder(
312 struct se_cmd *cmd,
313 unsigned char *cdb,
314 u32 pr_reg_type)
315{
316 struct se_dev_entry *se_deve;
Andy Grovere3d6f902011-07-19 08:55:10 +0000317 struct se_session *se_sess = cmd->se_sess;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800318 int other_cdb = 0, ignore_reg;
319 int registered_nexus = 0, ret = 1; /* Conflict by default */
320 int all_reg = 0, reg_only = 0; /* ALL_REG, REG_ONLY */
321 int we = 0; /* Write Exclusive */
322 int legacy = 0; /* Act like a legacy device and return
323 * RESERVATION CONFLICT on some CDBs */
324 /*
325 * A legacy SPC-2 reservation is being held.
326 */
327 if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS)
328 return core_scsi2_reservation_seq_non_holder(cmd,
329 cdb, pr_reg_type);
330
331 se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
332 /*
333 * Determine if the registration should be ignored due to
334 * non-matching ISIDs in core_scsi3_pr_reservation_check().
335 */
336 ignore_reg = (pr_reg_type & 0x80000000);
337 if (ignore_reg)
338 pr_reg_type &= ~0x80000000;
339
340 switch (pr_reg_type) {
341 case PR_TYPE_WRITE_EXCLUSIVE:
342 we = 1;
343 case PR_TYPE_EXCLUSIVE_ACCESS:
344 /*
345 * Some commands are only allowed for the persistent reservation
346 * holder.
347 */
348 if ((se_deve->def_pr_registered) && !(ignore_reg))
349 registered_nexus = 1;
350 break;
351 case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
352 we = 1;
353 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
354 /*
355 * Some commands are only allowed for registered I_T Nexuses.
356 */
357 reg_only = 1;
358 if ((se_deve->def_pr_registered) && !(ignore_reg))
359 registered_nexus = 1;
360 break;
361 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
362 we = 1;
363 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
364 /*
365 * Each registered I_T Nexus is a reservation holder.
366 */
367 all_reg = 1;
368 if ((se_deve->def_pr_registered) && !(ignore_reg))
369 registered_nexus = 1;
370 break;
371 default:
Andy Grovere3d6f902011-07-19 08:55:10 +0000372 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800373 }
374 /*
375 * Referenced from spc4r17 table 45 for *NON* PR holder access
376 */
377 switch (cdb[0]) {
378 case SECURITY_PROTOCOL_IN:
379 if (registered_nexus)
380 return 0;
381 ret = (we) ? 0 : 1;
382 break;
383 case MODE_SENSE:
384 case MODE_SENSE_10:
385 case READ_ATTRIBUTE:
386 case READ_BUFFER:
387 case RECEIVE_DIAGNOSTIC:
388 if (legacy) {
389 ret = 1;
390 break;
391 }
392 if (registered_nexus) {
393 ret = 0;
394 break;
395 }
396 ret = (we) ? 0 : 1; /* Allowed Write Exclusive */
397 break;
398 case PERSISTENT_RESERVE_OUT:
399 /*
400 * This follows PERSISTENT_RESERVE_OUT service actions that
401 * are allowed in the presence of various reservations.
402 * See spc4r17, table 46
403 */
404 switch (cdb[1] & 0x1f) {
405 case PRO_CLEAR:
406 case PRO_PREEMPT:
407 case PRO_PREEMPT_AND_ABORT:
408 ret = (registered_nexus) ? 0 : 1;
409 break;
410 case PRO_REGISTER:
411 case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
412 ret = 0;
413 break;
414 case PRO_REGISTER_AND_MOVE:
415 case PRO_RESERVE:
416 ret = 1;
417 break;
418 case PRO_RELEASE:
419 ret = (registered_nexus) ? 0 : 1;
420 break;
421 default:
Andy Grover6708bb22011-06-08 10:36:43 -0700422 pr_err("Unknown PERSISTENT_RESERVE_OUT service"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800423 " action: 0x%02x\n", cdb[1] & 0x1f);
Andy Grovere3d6f902011-07-19 08:55:10 +0000424 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800425 }
426 break;
427 case RELEASE:
428 case RELEASE_10:
Christoph Hellwigeacac002011-11-03 17:50:40 -0400429 /* Handled by CRH=1 in target_scsi2_reservation_release() */
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800430 ret = 0;
431 break;
432 case RESERVE:
433 case RESERVE_10:
Christoph Hellwigeacac002011-11-03 17:50:40 -0400434 /* Handled by CRH=1 in target_scsi2_reservation_reserve() */
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800435 ret = 0;
436 break;
437 case TEST_UNIT_READY:
438 ret = (legacy) ? 1 : 0; /* Conflict for legacy */
439 break;
440 case MAINTENANCE_IN:
441 switch (cdb[1] & 0x1f) {
442 case MI_MANAGEMENT_PROTOCOL_IN:
443 if (registered_nexus) {
444 ret = 0;
445 break;
446 }
447 ret = (we) ? 0 : 1; /* Allowed Write Exclusive */
448 break;
449 case MI_REPORT_SUPPORTED_OPERATION_CODES:
450 case MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS:
451 if (legacy) {
452 ret = 1;
453 break;
454 }
455 if (registered_nexus) {
456 ret = 0;
457 break;
458 }
459 ret = (we) ? 0 : 1; /* Allowed Write Exclusive */
460 break;
461 case MI_REPORT_ALIASES:
462 case MI_REPORT_IDENTIFYING_INFORMATION:
463 case MI_REPORT_PRIORITY:
464 case MI_REPORT_TARGET_PGS:
465 case MI_REPORT_TIMESTAMP:
466 ret = 0; /* Allowed */
467 break;
468 default:
Andy Grover6708bb22011-06-08 10:36:43 -0700469 pr_err("Unknown MI Service Action: 0x%02x\n",
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800470 (cdb[1] & 0x1f));
Andy Grovere3d6f902011-07-19 08:55:10 +0000471 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800472 }
473 break;
474 case ACCESS_CONTROL_IN:
475 case ACCESS_CONTROL_OUT:
476 case INQUIRY:
477 case LOG_SENSE:
478 case READ_MEDIA_SERIAL_NUMBER:
479 case REPORT_LUNS:
480 case REQUEST_SENSE:
Marco Sanvido68169662012-01-03 17:12:58 -0800481 case PERSISTENT_RESERVE_IN:
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800482 ret = 0; /*/ Allowed CDBs */
483 break;
484 default:
485 other_cdb = 1;
486 break;
487 }
488 /*
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300489 * Case where the CDB is explicitly allowed in the above switch
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800490 * statement.
491 */
Andy Grover6708bb22011-06-08 10:36:43 -0700492 if (!ret && !other_cdb) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800493#if 0
Andy Grover6708bb22011-06-08 10:36:43 -0700494 pr_debug("Allowing explict CDB: 0x%02x for %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800495 " reservation holder\n", cdb[0],
496 core_scsi3_pr_dump_type(pr_reg_type));
497#endif
498 return ret;
499 }
500 /*
501 * Check if write exclusive initiator ports *NOT* holding the
502 * WRITE_EXCLUSIVE_* reservation.
503 */
504 if ((we) && !(registered_nexus)) {
505 if (cmd->data_direction == DMA_TO_DEVICE) {
506 /*
507 * Conflict for write exclusive
508 */
Andy Grover6708bb22011-06-08 10:36:43 -0700509 pr_debug("%s Conflict for unregistered nexus"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800510 " %s CDB: 0x%02x to %s reservation\n",
511 transport_dump_cmd_direction(cmd),
512 se_sess->se_node_acl->initiatorname, cdb[0],
513 core_scsi3_pr_dump_type(pr_reg_type));
514 return 1;
515 } else {
516 /*
517 * Allow non WRITE CDBs for all Write Exclusive
518 * PR TYPEs to pass for registered and
519 * non-registered_nexuxes NOT holding the reservation.
520 *
521 * We only make noise for the unregisterd nexuses,
522 * as we expect registered non-reservation holding
523 * nexuses to issue CDBs.
524 */
525#if 0
Andy Grover6708bb22011-06-08 10:36:43 -0700526 if (!registered_nexus) {
527 pr_debug("Allowing implict CDB: 0x%02x"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800528 " for %s reservation on unregistered"
529 " nexus\n", cdb[0],
530 core_scsi3_pr_dump_type(pr_reg_type));
531 }
532#endif
533 return 0;
534 }
535 } else if ((reg_only) || (all_reg)) {
536 if (registered_nexus) {
537 /*
538 * For PR_*_REG_ONLY and PR_*_ALL_REG reservations,
539 * allow commands from registered nexuses.
540 */
541#if 0
Andy Grover6708bb22011-06-08 10:36:43 -0700542 pr_debug("Allowing implict CDB: 0x%02x for %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800543 " reservation\n", cdb[0],
544 core_scsi3_pr_dump_type(pr_reg_type));
545#endif
546 return 0;
547 }
548 }
Andy Grover6708bb22011-06-08 10:36:43 -0700549 pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800550 " for %s reservation\n", transport_dump_cmd_direction(cmd),
551 (registered_nexus) ? "" : "un",
552 se_sess->se_node_acl->initiatorname, cdb[0],
553 core_scsi3_pr_dump_type(pr_reg_type));
554
555 return 1; /* Conflict by default */
556}
557
558static u32 core_scsi3_pr_generation(struct se_device *dev)
559{
Andy Grovere3d6f902011-07-19 08:55:10 +0000560 struct se_subsystem_dev *su_dev = dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800561 u32 prg;
562 /*
563 * PRGeneration field shall contain the value of a 32-bit wrapping
564 * counter mainted by the device server.
565 *
566 * Note that this is done regardless of Active Persist across
567 * Target PowerLoss (APTPL)
568 *
569 * See spc4r17 section 6.3.12 READ_KEYS service action
570 */
571 spin_lock(&dev->dev_reservation_lock);
Andy Grovere3d6f902011-07-19 08:55:10 +0000572 prg = su_dev->t10_pr.pr_generation++;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800573 spin_unlock(&dev->dev_reservation_lock);
574
575 return prg;
576}
577
578static int core_scsi3_pr_reservation_check(
579 struct se_cmd *cmd,
580 u32 *pr_reg_type)
581{
582 struct se_device *dev = cmd->se_dev;
583 struct se_session *sess = cmd->se_sess;
584 int ret;
585
Andy Grover6708bb22011-06-08 10:36:43 -0700586 if (!sess)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800587 return 0;
588 /*
589 * A legacy SPC-2 reservation is being held.
590 */
591 if (dev->dev_flags & DF_SPC2_RESERVATIONS)
592 return core_scsi2_reservation_check(cmd, pr_reg_type);
593
594 spin_lock(&dev->dev_reservation_lock);
Andy Grover6708bb22011-06-08 10:36:43 -0700595 if (!dev->dev_pr_res_holder) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800596 spin_unlock(&dev->dev_reservation_lock);
597 return 0;
598 }
599 *pr_reg_type = dev->dev_pr_res_holder->pr_res_type;
600 cmd->pr_res_key = dev->dev_pr_res_holder->pr_res_key;
601 if (dev->dev_pr_res_holder->pr_reg_nacl != sess->se_node_acl) {
602 spin_unlock(&dev->dev_reservation_lock);
Andy Grovere3d6f902011-07-19 08:55:10 +0000603 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800604 }
Andy Grover6708bb22011-06-08 10:36:43 -0700605 if (!dev->dev_pr_res_holder->isid_present_at_reg) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800606 spin_unlock(&dev->dev_reservation_lock);
607 return 0;
608 }
609 ret = (dev->dev_pr_res_holder->pr_reg_bin_isid ==
Andy Grovere3d6f902011-07-19 08:55:10 +0000610 sess->sess_bin_isid) ? 0 : -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800611 /*
612 * Use bit in *pr_reg_type to notify ISID mismatch in
613 * core_scsi3_pr_seq_non_holder().
614 */
615 if (ret != 0)
616 *pr_reg_type |= 0x80000000;
617 spin_unlock(&dev->dev_reservation_lock);
618
619 return ret;
620}
621
622static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
623 struct se_device *dev,
624 struct se_node_acl *nacl,
625 struct se_dev_entry *deve,
626 unsigned char *isid,
627 u64 sa_res_key,
628 int all_tg_pt,
629 int aptpl)
630{
Andy Grovere3d6f902011-07-19 08:55:10 +0000631 struct se_subsystem_dev *su_dev = dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800632 struct t10_pr_registration *pr_reg;
633
634 pr_reg = kmem_cache_zalloc(t10_pr_reg_cache, GFP_ATOMIC);
Andy Grover6708bb22011-06-08 10:36:43 -0700635 if (!pr_reg) {
636 pr_err("Unable to allocate struct t10_pr_registration\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800637 return NULL;
638 }
639
Andy Grovere3d6f902011-07-19 08:55:10 +0000640 pr_reg->pr_aptpl_buf = kzalloc(su_dev->t10_pr.pr_aptpl_buf_len,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800641 GFP_ATOMIC);
Andy Grover6708bb22011-06-08 10:36:43 -0700642 if (!pr_reg->pr_aptpl_buf) {
643 pr_err("Unable to allocate pr_reg->pr_aptpl_buf\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800644 kmem_cache_free(t10_pr_reg_cache, pr_reg);
645 return NULL;
646 }
647
648 INIT_LIST_HEAD(&pr_reg->pr_reg_list);
649 INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list);
650 INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list);
651 INIT_LIST_HEAD(&pr_reg->pr_reg_atp_list);
652 INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list);
653 atomic_set(&pr_reg->pr_res_holders, 0);
654 pr_reg->pr_reg_nacl = nacl;
655 pr_reg->pr_reg_deve = deve;
656 pr_reg->pr_res_mapped_lun = deve->mapped_lun;
657 pr_reg->pr_aptpl_target_lun = deve->se_lun->unpacked_lun;
658 pr_reg->pr_res_key = sa_res_key;
659 pr_reg->pr_reg_all_tg_pt = all_tg_pt;
660 pr_reg->pr_reg_aptpl = aptpl;
661 pr_reg->pr_reg_tg_pt_lun = deve->se_lun;
662 /*
663 * If an ISID value for this SCSI Initiator Port exists,
664 * save it to the registration now.
665 */
666 if (isid != NULL) {
667 pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
668 snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
669 pr_reg->isid_present_at_reg = 1;
670 }
671
672 return pr_reg;
673}
674
675static int core_scsi3_lunacl_depend_item(struct se_dev_entry *);
676static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *);
677
678/*
679 * Function used for handling PR registrations for ALL_TG_PT=1 and ALL_TG_PT=0
680 * modes.
681 */
682static struct t10_pr_registration *__core_scsi3_alloc_registration(
683 struct se_device *dev,
684 struct se_node_acl *nacl,
685 struct se_dev_entry *deve,
686 unsigned char *isid,
687 u64 sa_res_key,
688 int all_tg_pt,
689 int aptpl)
690{
691 struct se_dev_entry *deve_tmp;
692 struct se_node_acl *nacl_tmp;
693 struct se_port *port, *port_tmp;
694 struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo;
695 struct t10_pr_registration *pr_reg, *pr_reg_atp, *pr_reg_tmp, *pr_reg_tmp_safe;
696 int ret;
697 /*
698 * Create a registration for the I_T Nexus upon which the
699 * PROUT REGISTER was received.
700 */
701 pr_reg = __core_scsi3_do_alloc_registration(dev, nacl, deve, isid,
702 sa_res_key, all_tg_pt, aptpl);
Andy Grover6708bb22011-06-08 10:36:43 -0700703 if (!pr_reg)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800704 return NULL;
705 /*
706 * Return pointer to pr_reg for ALL_TG_PT=0
707 */
Andy Grover6708bb22011-06-08 10:36:43 -0700708 if (!all_tg_pt)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800709 return pr_reg;
710 /*
711 * Create list of matching SCSI Initiator Port registrations
712 * for ALL_TG_PT=1
713 */
714 spin_lock(&dev->se_port_lock);
715 list_for_each_entry_safe(port, port_tmp, &dev->dev_sep_list, sep_list) {
716 atomic_inc(&port->sep_tg_pt_ref_cnt);
717 smp_mb__after_atomic_inc();
718 spin_unlock(&dev->se_port_lock);
719
720 spin_lock_bh(&port->sep_alua_lock);
721 list_for_each_entry(deve_tmp, &port->sep_alua_list,
722 alua_port_list) {
723 /*
724 * This pointer will be NULL for demo mode MappedLUNs
725 * that have not been make explict via a ConfigFS
726 * MappedLUN group for the SCSI Initiator Node ACL.
727 */
Andy Grover6708bb22011-06-08 10:36:43 -0700728 if (!deve_tmp->se_lun_acl)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800729 continue;
730
731 nacl_tmp = deve_tmp->se_lun_acl->se_lun_nacl;
732 /*
733 * Skip the matching struct se_node_acl that is allocated
734 * above..
735 */
736 if (nacl == nacl_tmp)
737 continue;
738 /*
739 * Only perform PR registrations for target ports on
740 * the same fabric module as the REGISTER w/ ALL_TG_PT=1
741 * arrived.
742 */
743 if (tfo != nacl_tmp->se_tpg->se_tpg_tfo)
744 continue;
745 /*
746 * Look for a matching Initiator Node ACL in ASCII format
747 */
748 if (strcmp(nacl->initiatorname, nacl_tmp->initiatorname))
749 continue;
750
751 atomic_inc(&deve_tmp->pr_ref_count);
752 smp_mb__after_atomic_inc();
753 spin_unlock_bh(&port->sep_alua_lock);
754 /*
755 * Grab a configfs group dependency that is released
756 * for the exception path at label out: below, or upon
757 * completion of adding ALL_TG_PT=1 registrations in
758 * __core_scsi3_add_registration()
759 */
760 ret = core_scsi3_lunacl_depend_item(deve_tmp);
761 if (ret < 0) {
Andy Grover6708bb22011-06-08 10:36:43 -0700762 pr_err("core_scsi3_lunacl_depend"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800763 "_item() failed\n");
764 atomic_dec(&port->sep_tg_pt_ref_cnt);
765 smp_mb__after_atomic_dec();
766 atomic_dec(&deve_tmp->pr_ref_count);
767 smp_mb__after_atomic_dec();
768 goto out;
769 }
770 /*
771 * Located a matching SCSI Initiator Port on a different
772 * port, allocate the pr_reg_atp and attach it to the
773 * pr_reg->pr_reg_atp_list that will be processed once
774 * the original *pr_reg is processed in
775 * __core_scsi3_add_registration()
776 */
777 pr_reg_atp = __core_scsi3_do_alloc_registration(dev,
778 nacl_tmp, deve_tmp, NULL,
779 sa_res_key, all_tg_pt, aptpl);
Andy Grover6708bb22011-06-08 10:36:43 -0700780 if (!pr_reg_atp) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800781 atomic_dec(&port->sep_tg_pt_ref_cnt);
782 smp_mb__after_atomic_dec();
783 atomic_dec(&deve_tmp->pr_ref_count);
784 smp_mb__after_atomic_dec();
785 core_scsi3_lunacl_undepend_item(deve_tmp);
786 goto out;
787 }
788
789 list_add_tail(&pr_reg_atp->pr_reg_atp_mem_list,
790 &pr_reg->pr_reg_atp_list);
791 spin_lock_bh(&port->sep_alua_lock);
792 }
793 spin_unlock_bh(&port->sep_alua_lock);
794
795 spin_lock(&dev->se_port_lock);
796 atomic_dec(&port->sep_tg_pt_ref_cnt);
797 smp_mb__after_atomic_dec();
798 }
799 spin_unlock(&dev->se_port_lock);
800
801 return pr_reg;
802out:
803 list_for_each_entry_safe(pr_reg_tmp, pr_reg_tmp_safe,
804 &pr_reg->pr_reg_atp_list, pr_reg_atp_mem_list) {
805 list_del(&pr_reg_tmp->pr_reg_atp_mem_list);
806 core_scsi3_lunacl_undepend_item(pr_reg_tmp->pr_reg_deve);
807 kmem_cache_free(t10_pr_reg_cache, pr_reg_tmp);
808 }
809 kmem_cache_free(t10_pr_reg_cache, pr_reg);
810 return NULL;
811}
812
813int core_scsi3_alloc_aptpl_registration(
Andy Grovere3d6f902011-07-19 08:55:10 +0000814 struct t10_reservation *pr_tmpl,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800815 u64 sa_res_key,
816 unsigned char *i_port,
817 unsigned char *isid,
818 u32 mapped_lun,
819 unsigned char *t_port,
820 u16 tpgt,
821 u32 target_lun,
822 int res_holder,
823 int all_tg_pt,
824 u8 type)
825{
826 struct t10_pr_registration *pr_reg;
827
Andy Grover6708bb22011-06-08 10:36:43 -0700828 if (!i_port || !t_port || !sa_res_key) {
829 pr_err("Illegal parameters for APTPL registration\n");
Andy Grovere3d6f902011-07-19 08:55:10 +0000830 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800831 }
832
833 pr_reg = kmem_cache_zalloc(t10_pr_reg_cache, GFP_KERNEL);
Andy Grover6708bb22011-06-08 10:36:43 -0700834 if (!pr_reg) {
835 pr_err("Unable to allocate struct t10_pr_registration\n");
Andy Grovere3d6f902011-07-19 08:55:10 +0000836 return -ENOMEM;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800837 }
838 pr_reg->pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len, GFP_KERNEL);
839
840 INIT_LIST_HEAD(&pr_reg->pr_reg_list);
841 INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list);
842 INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list);
843 INIT_LIST_HEAD(&pr_reg->pr_reg_atp_list);
844 INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list);
845 atomic_set(&pr_reg->pr_res_holders, 0);
846 pr_reg->pr_reg_nacl = NULL;
847 pr_reg->pr_reg_deve = NULL;
848 pr_reg->pr_res_mapped_lun = mapped_lun;
849 pr_reg->pr_aptpl_target_lun = target_lun;
850 pr_reg->pr_res_key = sa_res_key;
851 pr_reg->pr_reg_all_tg_pt = all_tg_pt;
852 pr_reg->pr_reg_aptpl = 1;
853 pr_reg->pr_reg_tg_pt_lun = NULL;
854 pr_reg->pr_res_scope = 0; /* Always LUN_SCOPE */
855 pr_reg->pr_res_type = type;
856 /*
857 * If an ISID value had been saved in APTPL metadata for this
858 * SCSI Initiator Port, restore it now.
859 */
860 if (isid != NULL) {
861 pr_reg->pr_reg_bin_isid = get_unaligned_be64(isid);
862 snprintf(pr_reg->pr_reg_isid, PR_REG_ISID_LEN, "%s", isid);
863 pr_reg->isid_present_at_reg = 1;
864 }
865 /*
866 * Copy the i_port and t_port information from caller.
867 */
868 snprintf(pr_reg->pr_iport, PR_APTPL_MAX_IPORT_LEN, "%s", i_port);
869 snprintf(pr_reg->pr_tport, PR_APTPL_MAX_TPORT_LEN, "%s", t_port);
870 pr_reg->pr_reg_tpgt = tpgt;
871 /*
872 * Set pr_res_holder from caller, the pr_reg who is the reservation
873 * holder will get it's pointer set in core_scsi3_aptpl_reserve() once
874 * the Initiator Node LUN ACL from the fabric module is created for
875 * this registration.
876 */
877 pr_reg->pr_res_holder = res_holder;
878
879 list_add_tail(&pr_reg->pr_reg_aptpl_list, &pr_tmpl->aptpl_reg_list);
Andy Grover6708bb22011-06-08 10:36:43 -0700880 pr_debug("SPC-3 PR APTPL Successfully added registration%s from"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800881 " metadata\n", (res_holder) ? "+reservation" : "");
882 return 0;
883}
884
885static void core_scsi3_aptpl_reserve(
886 struct se_device *dev,
887 struct se_portal_group *tpg,
888 struct se_node_acl *node_acl,
889 struct t10_pr_registration *pr_reg)
890{
891 char i_buf[PR_REG_ISID_ID_LEN];
892 int prf_isid;
893
894 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
895 prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
896 PR_REG_ISID_ID_LEN);
897
898 spin_lock(&dev->dev_reservation_lock);
899 dev->dev_pr_res_holder = pr_reg;
900 spin_unlock(&dev->dev_reservation_lock);
901
Andy Grover6708bb22011-06-08 10:36:43 -0700902 pr_debug("SPC-3 PR [%s] Service Action: APTPL RESERVE created"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800903 " new reservation holder TYPE: %s ALL_TG_PT: %d\n",
Andy Grovere3d6f902011-07-19 08:55:10 +0000904 tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800905 core_scsi3_pr_dump_type(pr_reg->pr_res_type),
906 (pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
Andy Grover6708bb22011-06-08 10:36:43 -0700907 pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n",
Andy Grovere3d6f902011-07-19 08:55:10 +0000908 tpg->se_tpg_tfo->get_fabric_name(), node_acl->initiatorname,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800909 (prf_isid) ? &i_buf[0] : "");
910}
911
912static void __core_scsi3_add_registration(struct se_device *, struct se_node_acl *,
913 struct t10_pr_registration *, int, int);
914
915static int __core_scsi3_check_aptpl_registration(
916 struct se_device *dev,
917 struct se_portal_group *tpg,
918 struct se_lun *lun,
919 u32 target_lun,
920 struct se_node_acl *nacl,
921 struct se_dev_entry *deve)
922{
923 struct t10_pr_registration *pr_reg, *pr_reg_tmp;
Andy Grovere3d6f902011-07-19 08:55:10 +0000924 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800925 unsigned char i_port[PR_APTPL_MAX_IPORT_LEN];
926 unsigned char t_port[PR_APTPL_MAX_TPORT_LEN];
927 u16 tpgt;
928
929 memset(i_port, 0, PR_APTPL_MAX_IPORT_LEN);
930 memset(t_port, 0, PR_APTPL_MAX_TPORT_LEN);
931 /*
932 * Copy Initiator Port information from struct se_node_acl
933 */
934 snprintf(i_port, PR_APTPL_MAX_IPORT_LEN, "%s", nacl->initiatorname);
935 snprintf(t_port, PR_APTPL_MAX_TPORT_LEN, "%s",
Andy Grovere3d6f902011-07-19 08:55:10 +0000936 tpg->se_tpg_tfo->tpg_get_wwn(tpg));
937 tpgt = tpg->se_tpg_tfo->tpg_get_tag(tpg);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800938 /*
939 * Look for the matching registrations+reservation from those
940 * created from APTPL metadata. Note that multiple registrations
941 * may exist for fabrics that use ISIDs in their SCSI Initiator Port
942 * TransportIDs.
943 */
944 spin_lock(&pr_tmpl->aptpl_reg_lock);
945 list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list,
946 pr_reg_aptpl_list) {
Andy Grover6708bb22011-06-08 10:36:43 -0700947 if (!strcmp(pr_reg->pr_iport, i_port) &&
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800948 (pr_reg->pr_res_mapped_lun == deve->mapped_lun) &&
949 !(strcmp(pr_reg->pr_tport, t_port)) &&
950 (pr_reg->pr_reg_tpgt == tpgt) &&
951 (pr_reg->pr_aptpl_target_lun == target_lun)) {
952
953 pr_reg->pr_reg_nacl = nacl;
954 pr_reg->pr_reg_deve = deve;
955 pr_reg->pr_reg_tg_pt_lun = lun;
956
957 list_del(&pr_reg->pr_reg_aptpl_list);
958 spin_unlock(&pr_tmpl->aptpl_reg_lock);
959 /*
960 * At this point all of the pointers in *pr_reg will
961 * be setup, so go ahead and add the registration.
962 */
963
964 __core_scsi3_add_registration(dev, nacl, pr_reg, 0, 0);
965 /*
966 * If this registration is the reservation holder,
967 * make that happen now..
968 */
969 if (pr_reg->pr_res_holder)
970 core_scsi3_aptpl_reserve(dev, tpg,
971 nacl, pr_reg);
972 /*
973 * Reenable pr_aptpl_active to accept new metadata
974 * updates once the SCSI device is active again..
975 */
976 spin_lock(&pr_tmpl->aptpl_reg_lock);
977 pr_tmpl->pr_aptpl_active = 1;
978 }
979 }
980 spin_unlock(&pr_tmpl->aptpl_reg_lock);
981
982 return 0;
983}
984
985int core_scsi3_check_aptpl_registration(
986 struct se_device *dev,
987 struct se_portal_group *tpg,
988 struct se_lun *lun,
989 struct se_lun_acl *lun_acl)
990{
Andy Grovere3d6f902011-07-19 08:55:10 +0000991 struct se_subsystem_dev *su_dev = dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800992 struct se_node_acl *nacl = lun_acl->se_lun_nacl;
993 struct se_dev_entry *deve = &nacl->device_list[lun_acl->mapped_lun];
994
Andy Grovere3d6f902011-07-19 08:55:10 +0000995 if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -0800996 return 0;
997
998 return __core_scsi3_check_aptpl_registration(dev, tpg, lun,
999 lun->unpacked_lun, nacl, deve);
1000}
1001
1002static void __core_scsi3_dump_registration(
1003 struct target_core_fabric_ops *tfo,
1004 struct se_device *dev,
1005 struct se_node_acl *nacl,
1006 struct t10_pr_registration *pr_reg,
1007 int register_type)
1008{
1009 struct se_portal_group *se_tpg = nacl->se_tpg;
1010 char i_buf[PR_REG_ISID_ID_LEN];
1011 int prf_isid;
1012
1013 memset(&i_buf[0], 0, PR_REG_ISID_ID_LEN);
1014 prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
1015 PR_REG_ISID_ID_LEN);
1016
Andy Grover6708bb22011-06-08 10:36:43 -07001017 pr_debug("SPC-3 PR [%s] Service Action: REGISTER%s Initiator"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001018 " Node: %s%s\n", tfo->get_fabric_name(), (register_type == 2) ?
1019 "_AND_MOVE" : (register_type == 1) ?
1020 "_AND_IGNORE_EXISTING_KEY" : "", nacl->initiatorname,
1021 (prf_isid) ? i_buf : "");
Andy Grover6708bb22011-06-08 10:36:43 -07001022 pr_debug("SPC-3 PR [%s] registration on Target Port: %s,0x%04x\n",
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001023 tfo->get_fabric_name(), tfo->tpg_get_wwn(se_tpg),
1024 tfo->tpg_get_tag(se_tpg));
Andy Grover6708bb22011-06-08 10:36:43 -07001025 pr_debug("SPC-3 PR [%s] for %s TCM Subsystem %s Object Target"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001026 " Port(s)\n", tfo->get_fabric_name(),
1027 (pr_reg->pr_reg_all_tg_pt) ? "ALL" : "SINGLE",
Andy Grovere3d6f902011-07-19 08:55:10 +00001028 dev->transport->name);
Andy Grover6708bb22011-06-08 10:36:43 -07001029 pr_debug("SPC-3 PR [%s] SA Res Key: 0x%016Lx PRgeneration:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001030 " 0x%08x APTPL: %d\n", tfo->get_fabric_name(),
1031 pr_reg->pr_res_key, pr_reg->pr_res_generation,
1032 pr_reg->pr_reg_aptpl);
1033}
1034
1035/*
1036 * this function can be called with struct se_device->dev_reservation_lock
1037 * when register_move = 1
1038 */
1039static void __core_scsi3_add_registration(
1040 struct se_device *dev,
1041 struct se_node_acl *nacl,
1042 struct t10_pr_registration *pr_reg,
1043 int register_type,
1044 int register_move)
1045{
Andy Grovere3d6f902011-07-19 08:55:10 +00001046 struct se_subsystem_dev *su_dev = dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001047 struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo;
1048 struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe;
Andy Grovere3d6f902011-07-19 08:55:10 +00001049 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001050
1051 /*
1052 * Increment PRgeneration counter for struct se_device upon a successful
1053 * REGISTER, see spc4r17 section 6.3.2 READ_KEYS service action
1054 *
1055 * Also, when register_move = 1 for PROUT REGISTER_AND_MOVE service
1056 * action, the struct se_device->dev_reservation_lock will already be held,
1057 * so we do not call core_scsi3_pr_generation() which grabs the lock
1058 * for the REGISTER.
1059 */
1060 pr_reg->pr_res_generation = (register_move) ?
Andy Grovere3d6f902011-07-19 08:55:10 +00001061 su_dev->t10_pr.pr_generation++ :
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001062 core_scsi3_pr_generation(dev);
1063
1064 spin_lock(&pr_tmpl->registration_lock);
1065 list_add_tail(&pr_reg->pr_reg_list, &pr_tmpl->registration_list);
1066 pr_reg->pr_reg_deve->def_pr_registered = 1;
1067
1068 __core_scsi3_dump_registration(tfo, dev, nacl, pr_reg, register_type);
1069 spin_unlock(&pr_tmpl->registration_lock);
1070 /*
1071 * Skip extra processing for ALL_TG_PT=0 or REGISTER_AND_MOVE.
1072 */
Andy Grover6708bb22011-06-08 10:36:43 -07001073 if (!pr_reg->pr_reg_all_tg_pt || register_move)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001074 return;
1075 /*
1076 * Walk pr_reg->pr_reg_atp_list and add registrations for ALL_TG_PT=1
1077 * allocated in __core_scsi3_alloc_registration()
1078 */
1079 list_for_each_entry_safe(pr_reg_tmp, pr_reg_tmp_safe,
1080 &pr_reg->pr_reg_atp_list, pr_reg_atp_mem_list) {
1081 list_del(&pr_reg_tmp->pr_reg_atp_mem_list);
1082
1083 pr_reg_tmp->pr_res_generation = core_scsi3_pr_generation(dev);
1084
1085 spin_lock(&pr_tmpl->registration_lock);
1086 list_add_tail(&pr_reg_tmp->pr_reg_list,
1087 &pr_tmpl->registration_list);
1088 pr_reg_tmp->pr_reg_deve->def_pr_registered = 1;
1089
1090 __core_scsi3_dump_registration(tfo, dev,
1091 pr_reg_tmp->pr_reg_nacl, pr_reg_tmp,
1092 register_type);
1093 spin_unlock(&pr_tmpl->registration_lock);
1094 /*
1095 * Drop configfs group dependency reference from
1096 * __core_scsi3_alloc_registration()
1097 */
1098 core_scsi3_lunacl_undepend_item(pr_reg_tmp->pr_reg_deve);
1099 }
1100}
1101
1102static int core_scsi3_alloc_registration(
1103 struct se_device *dev,
1104 struct se_node_acl *nacl,
1105 struct se_dev_entry *deve,
1106 unsigned char *isid,
1107 u64 sa_res_key,
1108 int all_tg_pt,
1109 int aptpl,
1110 int register_type,
1111 int register_move)
1112{
1113 struct t10_pr_registration *pr_reg;
1114
1115 pr_reg = __core_scsi3_alloc_registration(dev, nacl, deve, isid,
1116 sa_res_key, all_tg_pt, aptpl);
Andy Grover6708bb22011-06-08 10:36:43 -07001117 if (!pr_reg)
Andy Grovere3d6f902011-07-19 08:55:10 +00001118 return -EPERM;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001119
1120 __core_scsi3_add_registration(dev, nacl, pr_reg,
1121 register_type, register_move);
1122 return 0;
1123}
1124
1125static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
1126 struct se_device *dev,
1127 struct se_node_acl *nacl,
1128 unsigned char *isid)
1129{
Andy Grovere3d6f902011-07-19 08:55:10 +00001130 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001131 struct t10_pr_registration *pr_reg, *pr_reg_tmp;
1132 struct se_portal_group *tpg;
1133
1134 spin_lock(&pr_tmpl->registration_lock);
1135 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
1136 &pr_tmpl->registration_list, pr_reg_list) {
1137 /*
1138 * First look for a matching struct se_node_acl
1139 */
1140 if (pr_reg->pr_reg_nacl != nacl)
1141 continue;
1142
1143 tpg = pr_reg->pr_reg_nacl->se_tpg;
1144 /*
1145 * If this registration does NOT contain a fabric provided
1146 * ISID, then we have found a match.
1147 */
Andy Grover6708bb22011-06-08 10:36:43 -07001148 if (!pr_reg->isid_present_at_reg) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001149 /*
1150 * Determine if this SCSI device server requires that
1151 * SCSI Intiatior TransportID w/ ISIDs is enforced
1152 * for fabric modules (iSCSI) requiring them.
1153 */
Andy Grovere3d6f902011-07-19 08:55:10 +00001154 if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
1155 if (dev->se_sub_dev->se_dev_attrib.enforce_pr_isids)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001156 continue;
1157 }
1158 atomic_inc(&pr_reg->pr_res_holders);
1159 smp_mb__after_atomic_inc();
1160 spin_unlock(&pr_tmpl->registration_lock);
1161 return pr_reg;
1162 }
1163 /*
1164 * If the *pr_reg contains a fabric defined ISID for multi-value
1165 * SCSI Initiator Port TransportIDs, then we expect a valid
1166 * matching ISID to be provided by the local SCSI Initiator Port.
1167 */
Andy Grover6708bb22011-06-08 10:36:43 -07001168 if (!isid)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001169 continue;
1170 if (strcmp(isid, pr_reg->pr_reg_isid))
1171 continue;
1172
1173 atomic_inc(&pr_reg->pr_res_holders);
1174 smp_mb__after_atomic_inc();
1175 spin_unlock(&pr_tmpl->registration_lock);
1176 return pr_reg;
1177 }
1178 spin_unlock(&pr_tmpl->registration_lock);
1179
1180 return NULL;
1181}
1182
1183static struct t10_pr_registration *core_scsi3_locate_pr_reg(
1184 struct se_device *dev,
1185 struct se_node_acl *nacl,
1186 struct se_session *sess)
1187{
1188 struct se_portal_group *tpg = nacl->se_tpg;
1189 unsigned char buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
1190
Andy Grovere3d6f902011-07-19 08:55:10 +00001191 if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001192 memset(&buf[0], 0, PR_REG_ISID_LEN);
Andy Grovere3d6f902011-07-19 08:55:10 +00001193 tpg->se_tpg_tfo->sess_get_initiator_sid(sess, &buf[0],
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001194 PR_REG_ISID_LEN);
1195 isid_ptr = &buf[0];
1196 }
1197
1198 return __core_scsi3_locate_pr_reg(dev, nacl, isid_ptr);
1199}
1200
1201static void core_scsi3_put_pr_reg(struct t10_pr_registration *pr_reg)
1202{
1203 atomic_dec(&pr_reg->pr_res_holders);
1204 smp_mb__after_atomic_dec();
1205}
1206
1207static int core_scsi3_check_implict_release(
1208 struct se_device *dev,
1209 struct t10_pr_registration *pr_reg)
1210{
1211 struct se_node_acl *nacl = pr_reg->pr_reg_nacl;
1212 struct t10_pr_registration *pr_res_holder;
1213 int ret = 0;
1214
1215 spin_lock(&dev->dev_reservation_lock);
1216 pr_res_holder = dev->dev_pr_res_holder;
Andy Grover6708bb22011-06-08 10:36:43 -07001217 if (!pr_res_holder) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001218 spin_unlock(&dev->dev_reservation_lock);
1219 return ret;
1220 }
1221 if (pr_res_holder == pr_reg) {
1222 /*
1223 * Perform an implict RELEASE if the registration that
1224 * is being released is holding the reservation.
1225 *
1226 * From spc4r17, section 5.7.11.1:
1227 *
1228 * e) If the I_T nexus is the persistent reservation holder
1229 * and the persistent reservation is not an all registrants
1230 * type, then a PERSISTENT RESERVE OUT command with REGISTER
1231 * service action or REGISTER AND IGNORE EXISTING KEY
1232 * service action with the SERVICE ACTION RESERVATION KEY
1233 * field set to zero (see 5.7.11.3).
1234 */
1235 __core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0);
1236 ret = 1;
1237 /*
1238 * For 'All Registrants' reservation types, all existing
1239 * registrations are still processed as reservation holders
1240 * in core_scsi3_pr_seq_non_holder() after the initial
1241 * reservation holder is implictly released here.
1242 */
1243 } else if (pr_reg->pr_reg_all_tg_pt &&
1244 (!strcmp(pr_res_holder->pr_reg_nacl->initiatorname,
1245 pr_reg->pr_reg_nacl->initiatorname)) &&
1246 (pr_res_holder->pr_res_key == pr_reg->pr_res_key)) {
Andy Grover6708bb22011-06-08 10:36:43 -07001247 pr_err("SPC-3 PR: Unable to perform ALL_TG_PT=1"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001248 " UNREGISTER while existing reservation with matching"
1249 " key 0x%016Lx is present from another SCSI Initiator"
1250 " Port\n", pr_reg->pr_res_key);
Andy Grovere3d6f902011-07-19 08:55:10 +00001251 ret = -EPERM;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001252 }
1253 spin_unlock(&dev->dev_reservation_lock);
1254
1255 return ret;
1256}
1257
1258/*
Andy Grovere3d6f902011-07-19 08:55:10 +00001259 * Called with struct t10_reservation->registration_lock held.
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001260 */
1261static void __core_scsi3_free_registration(
1262 struct se_device *dev,
1263 struct t10_pr_registration *pr_reg,
1264 struct list_head *preempt_and_abort_list,
1265 int dec_holders)
1266{
1267 struct target_core_fabric_ops *tfo =
1268 pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo;
Andy Grovere3d6f902011-07-19 08:55:10 +00001269 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001270 char i_buf[PR_REG_ISID_ID_LEN];
1271 int prf_isid;
1272
1273 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
1274 prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
1275 PR_REG_ISID_ID_LEN);
1276
1277 pr_reg->pr_reg_deve->def_pr_registered = 0;
1278 pr_reg->pr_reg_deve->pr_res_key = 0;
1279 list_del(&pr_reg->pr_reg_list);
1280 /*
1281 * Caller accessing *pr_reg using core_scsi3_locate_pr_reg(),
1282 * so call core_scsi3_put_pr_reg() to decrement our reference.
1283 */
1284 if (dec_holders)
1285 core_scsi3_put_pr_reg(pr_reg);
1286 /*
1287 * Wait until all reference from any other I_T nexuses for this
1288 * *pr_reg have been released. Because list_del() is called above,
1289 * the last core_scsi3_put_pr_reg(pr_reg) will release this reference
1290 * count back to zero, and we release *pr_reg.
1291 */
1292 while (atomic_read(&pr_reg->pr_res_holders) != 0) {
1293 spin_unlock(&pr_tmpl->registration_lock);
Andy Grover6708bb22011-06-08 10:36:43 -07001294 pr_debug("SPC-3 PR [%s] waiting for pr_res_holders\n",
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001295 tfo->get_fabric_name());
1296 cpu_relax();
1297 spin_lock(&pr_tmpl->registration_lock);
1298 }
1299
Andy Grover6708bb22011-06-08 10:36:43 -07001300 pr_debug("SPC-3 PR [%s] Service Action: UNREGISTER Initiator"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001301 " Node: %s%s\n", tfo->get_fabric_name(),
1302 pr_reg->pr_reg_nacl->initiatorname,
1303 (prf_isid) ? &i_buf[0] : "");
Andy Grover6708bb22011-06-08 10:36:43 -07001304 pr_debug("SPC-3 PR [%s] for %s TCM Subsystem %s Object Target"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001305 " Port(s)\n", tfo->get_fabric_name(),
1306 (pr_reg->pr_reg_all_tg_pt) ? "ALL" : "SINGLE",
Andy Grovere3d6f902011-07-19 08:55:10 +00001307 dev->transport->name);
Andy Grover6708bb22011-06-08 10:36:43 -07001308 pr_debug("SPC-3 PR [%s] SA Res Key: 0x%016Lx PRgeneration:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001309 " 0x%08x\n", tfo->get_fabric_name(), pr_reg->pr_res_key,
1310 pr_reg->pr_res_generation);
1311
Andy Grover6708bb22011-06-08 10:36:43 -07001312 if (!preempt_and_abort_list) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001313 pr_reg->pr_reg_deve = NULL;
1314 pr_reg->pr_reg_nacl = NULL;
1315 kfree(pr_reg->pr_aptpl_buf);
1316 kmem_cache_free(t10_pr_reg_cache, pr_reg);
1317 return;
1318 }
1319 /*
1320 * For PREEMPT_AND_ABORT, the list of *pr_reg in preempt_and_abort_list
1321 * are released once the ABORT_TASK_SET has completed..
1322 */
1323 list_add_tail(&pr_reg->pr_reg_abort_list, preempt_and_abort_list);
1324}
1325
1326void core_scsi3_free_pr_reg_from_nacl(
1327 struct se_device *dev,
1328 struct se_node_acl *nacl)
1329{
Andy Grovere3d6f902011-07-19 08:55:10 +00001330 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001331 struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder;
1332 /*
1333 * If the passed se_node_acl matches the reservation holder,
1334 * release the reservation.
1335 */
1336 spin_lock(&dev->dev_reservation_lock);
1337 pr_res_holder = dev->dev_pr_res_holder;
1338 if ((pr_res_holder != NULL) &&
1339 (pr_res_holder->pr_reg_nacl == nacl))
1340 __core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0);
1341 spin_unlock(&dev->dev_reservation_lock);
1342 /*
1343 * Release any registration associated with the struct se_node_acl.
1344 */
1345 spin_lock(&pr_tmpl->registration_lock);
1346 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
1347 &pr_tmpl->registration_list, pr_reg_list) {
1348
1349 if (pr_reg->pr_reg_nacl != nacl)
1350 continue;
1351
1352 __core_scsi3_free_registration(dev, pr_reg, NULL, 0);
1353 }
1354 spin_unlock(&pr_tmpl->registration_lock);
1355}
1356
1357void core_scsi3_free_all_registrations(
1358 struct se_device *dev)
1359{
Andy Grovere3d6f902011-07-19 08:55:10 +00001360 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001361 struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder;
1362
1363 spin_lock(&dev->dev_reservation_lock);
1364 pr_res_holder = dev->dev_pr_res_holder;
1365 if (pr_res_holder != NULL) {
1366 struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
1367 __core_scsi3_complete_pro_release(dev, pr_res_nacl,
1368 pr_res_holder, 0);
1369 }
1370 spin_unlock(&dev->dev_reservation_lock);
1371
1372 spin_lock(&pr_tmpl->registration_lock);
1373 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
1374 &pr_tmpl->registration_list, pr_reg_list) {
1375
1376 __core_scsi3_free_registration(dev, pr_reg, NULL, 0);
1377 }
1378 spin_unlock(&pr_tmpl->registration_lock);
1379
1380 spin_lock(&pr_tmpl->aptpl_reg_lock);
1381 list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list,
1382 pr_reg_aptpl_list) {
1383 list_del(&pr_reg->pr_reg_aptpl_list);
1384 kfree(pr_reg->pr_aptpl_buf);
1385 kmem_cache_free(t10_pr_reg_cache, pr_reg);
1386 }
1387 spin_unlock(&pr_tmpl->aptpl_reg_lock);
1388}
1389
1390static int core_scsi3_tpg_depend_item(struct se_portal_group *tpg)
1391{
Andy Grovere3d6f902011-07-19 08:55:10 +00001392 return configfs_depend_item(tpg->se_tpg_tfo->tf_subsys,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001393 &tpg->tpg_group.cg_item);
1394}
1395
1396static void core_scsi3_tpg_undepend_item(struct se_portal_group *tpg)
1397{
Andy Grovere3d6f902011-07-19 08:55:10 +00001398 configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001399 &tpg->tpg_group.cg_item);
1400
1401 atomic_dec(&tpg->tpg_pr_ref_count);
1402 smp_mb__after_atomic_dec();
1403}
1404
1405static int core_scsi3_nodeacl_depend_item(struct se_node_acl *nacl)
1406{
1407 struct se_portal_group *tpg = nacl->se_tpg;
1408
1409 if (nacl->dynamic_node_acl)
1410 return 0;
1411
Andy Grovere3d6f902011-07-19 08:55:10 +00001412 return configfs_depend_item(tpg->se_tpg_tfo->tf_subsys,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001413 &nacl->acl_group.cg_item);
1414}
1415
1416static void core_scsi3_nodeacl_undepend_item(struct se_node_acl *nacl)
1417{
1418 struct se_portal_group *tpg = nacl->se_tpg;
1419
1420 if (nacl->dynamic_node_acl) {
1421 atomic_dec(&nacl->acl_pr_ref_count);
1422 smp_mb__after_atomic_dec();
1423 return;
1424 }
1425
Andy Grovere3d6f902011-07-19 08:55:10 +00001426 configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001427 &nacl->acl_group.cg_item);
1428
1429 atomic_dec(&nacl->acl_pr_ref_count);
1430 smp_mb__after_atomic_dec();
1431}
1432
1433static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve)
1434{
1435 struct se_lun_acl *lun_acl = se_deve->se_lun_acl;
1436 struct se_node_acl *nacl;
1437 struct se_portal_group *tpg;
1438 /*
1439 * For nacl->dynamic_node_acl=1
1440 */
Andy Grover6708bb22011-06-08 10:36:43 -07001441 if (!lun_acl)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001442 return 0;
1443
1444 nacl = lun_acl->se_lun_nacl;
1445 tpg = nacl->se_tpg;
1446
Andy Grovere3d6f902011-07-19 08:55:10 +00001447 return configfs_depend_item(tpg->se_tpg_tfo->tf_subsys,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001448 &lun_acl->se_lun_group.cg_item);
1449}
1450
1451static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
1452{
1453 struct se_lun_acl *lun_acl = se_deve->se_lun_acl;
1454 struct se_node_acl *nacl;
1455 struct se_portal_group *tpg;
1456 /*
1457 * For nacl->dynamic_node_acl=1
1458 */
Andy Grover6708bb22011-06-08 10:36:43 -07001459 if (!lun_acl) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001460 atomic_dec(&se_deve->pr_ref_count);
1461 smp_mb__after_atomic_dec();
1462 return;
1463 }
1464 nacl = lun_acl->se_lun_nacl;
1465 tpg = nacl->se_tpg;
1466
Andy Grovere3d6f902011-07-19 08:55:10 +00001467 configfs_undepend_item(tpg->se_tpg_tfo->tf_subsys,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001468 &lun_acl->se_lun_group.cg_item);
1469
1470 atomic_dec(&se_deve->pr_ref_count);
1471 smp_mb__after_atomic_dec();
1472}
1473
1474static int core_scsi3_decode_spec_i_port(
1475 struct se_cmd *cmd,
1476 struct se_portal_group *tpg,
1477 unsigned char *l_isid,
1478 u64 sa_res_key,
1479 int all_tg_pt,
1480 int aptpl)
1481{
Andy Grover59511462011-07-19 10:26:37 +00001482 struct se_device *dev = cmd->se_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001483 struct se_port *tmp_port;
1484 struct se_portal_group *dest_tpg = NULL, *tmp_tpg;
Andy Grovere3d6f902011-07-19 08:55:10 +00001485 struct se_session *se_sess = cmd->se_sess;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001486 struct se_node_acl *dest_node_acl = NULL;
1487 struct se_dev_entry *dest_se_deve = NULL, *local_se_deve;
1488 struct t10_pr_registration *dest_pr_reg, *local_pr_reg, *pr_reg_e;
1489 struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe;
1490 struct list_head tid_dest_list;
1491 struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;
1492 struct target_core_fabric_ops *tmp_tf_ops;
Andy Grover05d1c7c2011-07-20 19:13:28 +00001493 unsigned char *buf;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001494 unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident;
1495 char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN];
1496 u32 tpdl, tid_len = 0;
1497 int ret, dest_local_nexus, prf_isid;
1498 u32 dest_rtpi = 0;
1499
1500 memset(dest_iport, 0, 64);
1501 INIT_LIST_HEAD(&tid_dest_list);
1502
1503 local_se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
1504 /*
1505 * Allocate a struct pr_transport_id_holder and setup the
1506 * local_node_acl and local_se_deve pointers and add to
1507 * struct list_head tid_dest_list for add registration
1508 * processing in the loop of tid_dest_list below.
1509 */
1510 tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL);
Andy Grover6708bb22011-06-08 10:36:43 -07001511 if (!tidh_new) {
1512 pr_err("Unable to allocate tidh_new\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001513 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1514 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001515 }
1516 INIT_LIST_HEAD(&tidh_new->dest_list);
1517 tidh_new->dest_tpg = tpg;
1518 tidh_new->dest_node_acl = se_sess->se_node_acl;
1519 tidh_new->dest_se_deve = local_se_deve;
1520
Andy Grover59511462011-07-19 10:26:37 +00001521 local_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001522 se_sess->se_node_acl, local_se_deve, l_isid,
1523 sa_res_key, all_tg_pt, aptpl);
Andy Grover6708bb22011-06-08 10:36:43 -07001524 if (!local_pr_reg) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001525 kfree(tidh_new);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001526 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1527 return -ENOMEM;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001528 }
1529 tidh_new->dest_pr_reg = local_pr_reg;
1530 /*
1531 * The local I_T nexus does not hold any configfs dependances,
1532 * so we set tid_h->dest_local_nexus=1 to prevent the
1533 * configfs_undepend_item() calls in the tid_dest_list loops below.
1534 */
1535 tidh_new->dest_local_nexus = 1;
1536 list_add_tail(&tidh_new->dest_list, &tid_dest_list);
Andy Grover05d1c7c2011-07-20 19:13:28 +00001537
Andy Grover49493142012-01-16 16:57:08 -08001538 buf = transport_kmap_data_sg(cmd);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001539 /*
1540 * For a PERSISTENT RESERVE OUT specify initiator ports payload,
1541 * first extract TransportID Parameter Data Length, and make sure
1542 * the value matches up to the SCSI expected data transfer length.
1543 */
1544 tpdl = (buf[24] & 0xff) << 24;
1545 tpdl |= (buf[25] & 0xff) << 16;
1546 tpdl |= (buf[26] & 0xff) << 8;
1547 tpdl |= buf[27] & 0xff;
1548
1549 if ((tpdl + 28) != cmd->data_length) {
Andy Grover6708bb22011-06-08 10:36:43 -07001550 pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001551 " does not equal CDB data_length: %u\n", tpdl,
1552 cmd->data_length);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001553 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
1554 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001555 goto out;
1556 }
1557 /*
1558 * Start processing the received transport IDs using the
1559 * receiving I_T Nexus portal's fabric dependent methods to
1560 * obtain the SCSI Initiator Port/Device Identifiers.
1561 */
1562 ptr = &buf[28];
1563
1564 while (tpdl > 0) {
1565 proto_ident = (ptr[0] & 0x0f);
1566 dest_tpg = NULL;
1567
1568 spin_lock(&dev->se_port_lock);
1569 list_for_each_entry(tmp_port, &dev->dev_sep_list, sep_list) {
1570 tmp_tpg = tmp_port->sep_tpg;
Andy Grover6708bb22011-06-08 10:36:43 -07001571 if (!tmp_tpg)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001572 continue;
Andy Grovere3d6f902011-07-19 08:55:10 +00001573 tmp_tf_ops = tmp_tpg->se_tpg_tfo;
Andy Grover6708bb22011-06-08 10:36:43 -07001574 if (!tmp_tf_ops)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001575 continue;
Andy Grover6708bb22011-06-08 10:36:43 -07001576 if (!tmp_tf_ops->get_fabric_proto_ident ||
1577 !tmp_tf_ops->tpg_parse_pr_out_transport_id)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001578 continue;
1579 /*
1580 * Look for the matching proto_ident provided by
1581 * the received TransportID
1582 */
1583 tmp_proto_ident = tmp_tf_ops->get_fabric_proto_ident(tmp_tpg);
1584 if (tmp_proto_ident != proto_ident)
1585 continue;
1586 dest_rtpi = tmp_port->sep_rtpi;
1587
1588 i_str = tmp_tf_ops->tpg_parse_pr_out_transport_id(
1589 tmp_tpg, (const char *)ptr, &tid_len,
1590 &iport_ptr);
Andy Grover6708bb22011-06-08 10:36:43 -07001591 if (!i_str)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001592 continue;
1593
1594 atomic_inc(&tmp_tpg->tpg_pr_ref_count);
1595 smp_mb__after_atomic_inc();
1596 spin_unlock(&dev->se_port_lock);
1597
1598 ret = core_scsi3_tpg_depend_item(tmp_tpg);
1599 if (ret != 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07001600 pr_err(" core_scsi3_tpg_depend_item()"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001601 " for tmp_tpg\n");
1602 atomic_dec(&tmp_tpg->tpg_pr_ref_count);
1603 smp_mb__after_atomic_dec();
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001604 cmd->scsi_sense_reason =
1605 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1606 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001607 goto out;
1608 }
1609 /*
1610 * Locate the desination initiator ACL to be registered
1611 * from the decoded fabric module specific TransportID
1612 * at *i_str.
1613 */
Roland Dreier28638882011-08-16 09:40:01 -07001614 spin_lock_irq(&tmp_tpg->acl_node_lock);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001615 dest_node_acl = __core_tpg_get_initiator_node_acl(
1616 tmp_tpg, i_str);
1617 if (dest_node_acl) {
1618 atomic_inc(&dest_node_acl->acl_pr_ref_count);
1619 smp_mb__after_atomic_inc();
1620 }
Roland Dreier28638882011-08-16 09:40:01 -07001621 spin_unlock_irq(&tmp_tpg->acl_node_lock);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001622
Andy Grover6708bb22011-06-08 10:36:43 -07001623 if (!dest_node_acl) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001624 core_scsi3_tpg_undepend_item(tmp_tpg);
1625 spin_lock(&dev->se_port_lock);
1626 continue;
1627 }
1628
1629 ret = core_scsi3_nodeacl_depend_item(dest_node_acl);
1630 if (ret != 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07001631 pr_err("configfs_depend_item() failed"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001632 " for dest_node_acl->acl_group\n");
1633 atomic_dec(&dest_node_acl->acl_pr_ref_count);
1634 smp_mb__after_atomic_dec();
1635 core_scsi3_tpg_undepend_item(tmp_tpg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001636 cmd->scsi_sense_reason =
1637 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1638 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001639 goto out;
1640 }
1641
1642 dest_tpg = tmp_tpg;
Andy Grover6708bb22011-06-08 10:36:43 -07001643 pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001644 " %s Port RTPI: %hu\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00001645 dest_tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001646 dest_node_acl->initiatorname, dest_rtpi);
1647
1648 spin_lock(&dev->se_port_lock);
1649 break;
1650 }
1651 spin_unlock(&dev->se_port_lock);
1652
Andy Grover6708bb22011-06-08 10:36:43 -07001653 if (!dest_tpg) {
1654 pr_err("SPC-3 PR SPEC_I_PT: Unable to locate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001655 " dest_tpg\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001656 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
1657 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001658 goto out;
1659 }
1660#if 0
Andy Grover6708bb22011-06-08 10:36:43 -07001661 pr_debug("SPC-3 PR SPEC_I_PT: Got %s data_length: %u tpdl: %u"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001662 " tid_len: %d for %s + %s\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00001663 dest_tpg->se_tpg_tfo->get_fabric_name(), cmd->data_length,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001664 tpdl, tid_len, i_str, iport_ptr);
1665#endif
1666 if (tid_len > tpdl) {
Andy Grover6708bb22011-06-08 10:36:43 -07001667 pr_err("SPC-3 PR SPEC_I_PT: Illegal tid_len:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001668 " %u for Transport ID: %s\n", tid_len, ptr);
1669 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1670 core_scsi3_tpg_undepend_item(dest_tpg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001671 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
1672 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001673 goto out;
1674 }
1675 /*
1676 * Locate the desintation struct se_dev_entry pointer for matching
1677 * RELATIVE TARGET PORT IDENTIFIER on the receiving I_T Nexus
1678 * Target Port.
1679 */
1680 dest_se_deve = core_get_se_deve_from_rtpi(dest_node_acl,
1681 dest_rtpi);
Andy Grover6708bb22011-06-08 10:36:43 -07001682 if (!dest_se_deve) {
1683 pr_err("Unable to locate %s dest_se_deve"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001684 " from destination RTPI: %hu\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00001685 dest_tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001686 dest_rtpi);
1687
1688 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1689 core_scsi3_tpg_undepend_item(dest_tpg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001690 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
1691 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001692 goto out;
1693 }
1694
1695 ret = core_scsi3_lunacl_depend_item(dest_se_deve);
1696 if (ret < 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07001697 pr_err("core_scsi3_lunacl_depend_item()"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001698 " failed\n");
1699 atomic_dec(&dest_se_deve->pr_ref_count);
1700 smp_mb__after_atomic_dec();
1701 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1702 core_scsi3_tpg_undepend_item(dest_tpg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001703 cmd->scsi_sense_reason =
1704 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1705 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001706 goto out;
1707 }
1708#if 0
Andy Grover6708bb22011-06-08 10:36:43 -07001709 pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001710 " dest_se_deve mapped_lun: %u\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00001711 dest_tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001712 dest_node_acl->initiatorname, dest_se_deve->mapped_lun);
1713#endif
1714 /*
1715 * Skip any TransportIDs that already have a registration for
1716 * this target port.
1717 */
1718 pr_reg_e = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
1719 iport_ptr);
1720 if (pr_reg_e) {
1721 core_scsi3_put_pr_reg(pr_reg_e);
1722 core_scsi3_lunacl_undepend_item(dest_se_deve);
1723 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1724 core_scsi3_tpg_undepend_item(dest_tpg);
1725 ptr += tid_len;
1726 tpdl -= tid_len;
1727 tid_len = 0;
1728 continue;
1729 }
1730 /*
1731 * Allocate a struct pr_transport_id_holder and setup
1732 * the dest_node_acl and dest_se_deve pointers for the
1733 * loop below.
1734 */
1735 tidh_new = kzalloc(sizeof(struct pr_transport_id_holder),
1736 GFP_KERNEL);
Andy Grover6708bb22011-06-08 10:36:43 -07001737 if (!tidh_new) {
1738 pr_err("Unable to allocate tidh_new\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001739 core_scsi3_lunacl_undepend_item(dest_se_deve);
1740 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1741 core_scsi3_tpg_undepend_item(dest_tpg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001742 cmd->scsi_sense_reason =
1743 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1744 ret = -ENOMEM;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001745 goto out;
1746 }
1747 INIT_LIST_HEAD(&tidh_new->dest_list);
1748 tidh_new->dest_tpg = dest_tpg;
1749 tidh_new->dest_node_acl = dest_node_acl;
1750 tidh_new->dest_se_deve = dest_se_deve;
1751
1752 /*
1753 * Allocate, but do NOT add the registration for the
1754 * TransportID referenced SCSI Initiator port. This
1755 * done because of the following from spc4r17 in section
1756 * 6.14.3 wrt SPEC_I_PT:
1757 *
1758 * "If a registration fails for any initiator port (e.g., if th
1759 * logical unit does not have enough resources available to
1760 * hold the registration information), no registrations shall be
1761 * made, and the command shall be terminated with
1762 * CHECK CONDITION status."
1763 *
1764 * That means we call __core_scsi3_alloc_registration() here,
1765 * and then call __core_scsi3_add_registration() in the
1766 * 2nd loop which will never fail.
1767 */
Andy Grover59511462011-07-19 10:26:37 +00001768 dest_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001769 dest_node_acl, dest_se_deve, iport_ptr,
1770 sa_res_key, all_tg_pt, aptpl);
Andy Grover6708bb22011-06-08 10:36:43 -07001771 if (!dest_pr_reg) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001772 core_scsi3_lunacl_undepend_item(dest_se_deve);
1773 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1774 core_scsi3_tpg_undepend_item(dest_tpg);
1775 kfree(tidh_new);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07001776 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
1777 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001778 goto out;
1779 }
1780 tidh_new->dest_pr_reg = dest_pr_reg;
1781 list_add_tail(&tidh_new->dest_list, &tid_dest_list);
1782
1783 ptr += tid_len;
1784 tpdl -= tid_len;
1785 tid_len = 0;
1786
1787 }
Andy Grover05d1c7c2011-07-20 19:13:28 +00001788
Andy Grover49493142012-01-16 16:57:08 -08001789 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00001790
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001791 /*
1792 * Go ahead and create a registrations from tid_dest_list for the
1793 * SPEC_I_PT provided TransportID for the *tidh referenced dest_node_acl
1794 * and dest_se_deve.
1795 *
1796 * The SA Reservation Key from the PROUT is set for the
1797 * registration, and ALL_TG_PT is also passed. ALL_TG_PT=1
1798 * means that the TransportID Initiator port will be
1799 * registered on all of the target ports in the SCSI target device
1800 * ALL_TG_PT=0 means the registration will only be for the
1801 * SCSI target port the PROUT REGISTER with SPEC_I_PT=1
1802 * was received.
1803 */
1804 list_for_each_entry_safe(tidh, tidh_tmp, &tid_dest_list, dest_list) {
1805 dest_tpg = tidh->dest_tpg;
1806 dest_node_acl = tidh->dest_node_acl;
1807 dest_se_deve = tidh->dest_se_deve;
1808 dest_pr_reg = tidh->dest_pr_reg;
1809 dest_local_nexus = tidh->dest_local_nexus;
1810
1811 list_del(&tidh->dest_list);
1812 kfree(tidh);
1813
1814 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
1815 prf_isid = core_pr_dump_initiator_port(dest_pr_reg, &i_buf[0],
1816 PR_REG_ISID_ID_LEN);
1817
Andy Grover59511462011-07-19 10:26:37 +00001818 __core_scsi3_add_registration(cmd->se_dev, dest_node_acl,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001819 dest_pr_reg, 0, 0);
1820
Andy Grover6708bb22011-06-08 10:36:43 -07001821 pr_debug("SPC-3 PR [%s] SPEC_I_PT: Successfully"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001822 " registered Transport ID for Node: %s%s Mapped LUN:"
Andy Grovere3d6f902011-07-19 08:55:10 +00001823 " %u\n", dest_tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001824 dest_node_acl->initiatorname, (prf_isid) ?
1825 &i_buf[0] : "", dest_se_deve->mapped_lun);
1826
1827 if (dest_local_nexus)
1828 continue;
1829
1830 core_scsi3_lunacl_undepend_item(dest_se_deve);
1831 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1832 core_scsi3_tpg_undepend_item(dest_tpg);
1833 }
1834
1835 return 0;
1836out:
Andy Grover49493142012-01-16 16:57:08 -08001837 transport_kunmap_data_sg(cmd);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001838 /*
1839 * For the failure case, release everything from tid_dest_list
1840 * including *dest_pr_reg and the configfs dependances..
1841 */
1842 list_for_each_entry_safe(tidh, tidh_tmp, &tid_dest_list, dest_list) {
1843 dest_tpg = tidh->dest_tpg;
1844 dest_node_acl = tidh->dest_node_acl;
1845 dest_se_deve = tidh->dest_se_deve;
1846 dest_pr_reg = tidh->dest_pr_reg;
1847 dest_local_nexus = tidh->dest_local_nexus;
1848
1849 list_del(&tidh->dest_list);
1850 kfree(tidh);
1851 /*
1852 * Release any extra ALL_TG_PT=1 registrations for
1853 * the SPEC_I_PT=1 case.
1854 */
1855 list_for_each_entry_safe(pr_reg_tmp, pr_reg_tmp_safe,
1856 &dest_pr_reg->pr_reg_atp_list,
1857 pr_reg_atp_mem_list) {
1858 list_del(&pr_reg_tmp->pr_reg_atp_mem_list);
1859 core_scsi3_lunacl_undepend_item(pr_reg_tmp->pr_reg_deve);
1860 kmem_cache_free(t10_pr_reg_cache, pr_reg_tmp);
1861 }
1862
1863 kfree(dest_pr_reg->pr_aptpl_buf);
1864 kmem_cache_free(t10_pr_reg_cache, dest_pr_reg);
1865
1866 if (dest_local_nexus)
1867 continue;
1868
1869 core_scsi3_lunacl_undepend_item(dest_se_deve);
1870 core_scsi3_nodeacl_undepend_item(dest_node_acl);
1871 core_scsi3_tpg_undepend_item(dest_tpg);
1872 }
1873 return ret;
1874}
1875
1876/*
1877 * Called with struct se_device->dev_reservation_lock held
1878 */
1879static int __core_scsi3_update_aptpl_buf(
1880 struct se_device *dev,
1881 unsigned char *buf,
1882 u32 pr_aptpl_buf_len,
1883 int clear_aptpl_metadata)
1884{
1885 struct se_lun *lun;
1886 struct se_portal_group *tpg;
Andy Grovere3d6f902011-07-19 08:55:10 +00001887 struct se_subsystem_dev *su_dev = dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001888 struct t10_pr_registration *pr_reg;
1889 unsigned char tmp[512], isid_buf[32];
1890 ssize_t len = 0;
1891 int reg_count = 0;
1892
1893 memset(buf, 0, pr_aptpl_buf_len);
1894 /*
1895 * Called to clear metadata once APTPL has been deactivated.
1896 */
1897 if (clear_aptpl_metadata) {
1898 snprintf(buf, pr_aptpl_buf_len,
1899 "No Registrations or Reservations\n");
1900 return 0;
1901 }
1902 /*
1903 * Walk the registration list..
1904 */
Andy Grovere3d6f902011-07-19 08:55:10 +00001905 spin_lock(&su_dev->t10_pr.registration_lock);
1906 list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001907 pr_reg_list) {
1908
1909 tmp[0] = '\0';
1910 isid_buf[0] = '\0';
1911 tpg = pr_reg->pr_reg_nacl->se_tpg;
1912 lun = pr_reg->pr_reg_tg_pt_lun;
1913 /*
1914 * Write out any ISID value to APTPL metadata that was included
1915 * in the original registration.
1916 */
1917 if (pr_reg->isid_present_at_reg)
1918 snprintf(isid_buf, 32, "initiator_sid=%s\n",
1919 pr_reg->pr_reg_isid);
1920 /*
1921 * Include special metadata if the pr_reg matches the
1922 * reservation holder.
1923 */
1924 if (dev->dev_pr_res_holder == pr_reg) {
1925 snprintf(tmp, 512, "PR_REG_START: %d"
1926 "\ninitiator_fabric=%s\n"
1927 "initiator_node=%s\n%s"
1928 "sa_res_key=%llu\n"
1929 "res_holder=1\nres_type=%02x\n"
1930 "res_scope=%02x\nres_all_tg_pt=%d\n"
1931 "mapped_lun=%u\n", reg_count,
Andy Grovere3d6f902011-07-19 08:55:10 +00001932 tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001933 pr_reg->pr_reg_nacl->initiatorname, isid_buf,
1934 pr_reg->pr_res_key, pr_reg->pr_res_type,
1935 pr_reg->pr_res_scope, pr_reg->pr_reg_all_tg_pt,
1936 pr_reg->pr_res_mapped_lun);
1937 } else {
1938 snprintf(tmp, 512, "PR_REG_START: %d\n"
1939 "initiator_fabric=%s\ninitiator_node=%s\n%s"
1940 "sa_res_key=%llu\nres_holder=0\n"
1941 "res_all_tg_pt=%d\nmapped_lun=%u\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00001942 reg_count, tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001943 pr_reg->pr_reg_nacl->initiatorname, isid_buf,
1944 pr_reg->pr_res_key, pr_reg->pr_reg_all_tg_pt,
1945 pr_reg->pr_res_mapped_lun);
1946 }
1947
Dan Carpenter60d645a2011-06-15 10:03:05 -07001948 if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
Andy Grover6708bb22011-06-08 10:36:43 -07001949 pr_err("Unable to update renaming"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001950 " APTPL metadata\n");
Andy Grovere3d6f902011-07-19 08:55:10 +00001951 spin_unlock(&su_dev->t10_pr.registration_lock);
1952 return -EMSGSIZE;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001953 }
1954 len += sprintf(buf+len, "%s", tmp);
1955
1956 /*
1957 * Include information about the associated SCSI target port.
1958 */
1959 snprintf(tmp, 512, "target_fabric=%s\ntarget_node=%s\n"
1960 "tpgt=%hu\nport_rtpi=%hu\ntarget_lun=%u\nPR_REG_END:"
Andy Grovere3d6f902011-07-19 08:55:10 +00001961 " %d\n", tpg->se_tpg_tfo->get_fabric_name(),
1962 tpg->se_tpg_tfo->tpg_get_wwn(tpg),
1963 tpg->se_tpg_tfo->tpg_get_tag(tpg),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001964 lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count);
1965
Dan Carpenter60d645a2011-06-15 10:03:05 -07001966 if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
Andy Grover6708bb22011-06-08 10:36:43 -07001967 pr_err("Unable to update renaming"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001968 " APTPL metadata\n");
Andy Grovere3d6f902011-07-19 08:55:10 +00001969 spin_unlock(&su_dev->t10_pr.registration_lock);
1970 return -EMSGSIZE;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001971 }
1972 len += sprintf(buf+len, "%s", tmp);
1973 reg_count++;
1974 }
Andy Grovere3d6f902011-07-19 08:55:10 +00001975 spin_unlock(&su_dev->t10_pr.registration_lock);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001976
Andy Grover6708bb22011-06-08 10:36:43 -07001977 if (!reg_count)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08001978 len += sprintf(buf+len, "No Registrations or Reservations");
1979
1980 return 0;
1981}
1982
1983static int core_scsi3_update_aptpl_buf(
1984 struct se_device *dev,
1985 unsigned char *buf,
1986 u32 pr_aptpl_buf_len,
1987 int clear_aptpl_metadata)
1988{
1989 int ret;
1990
1991 spin_lock(&dev->dev_reservation_lock);
1992 ret = __core_scsi3_update_aptpl_buf(dev, buf, pr_aptpl_buf_len,
1993 clear_aptpl_metadata);
1994 spin_unlock(&dev->dev_reservation_lock);
1995
1996 return ret;
1997}
1998
1999/*
2000 * Called with struct se_device->aptpl_file_mutex held
2001 */
2002static int __core_scsi3_write_aptpl_to_file(
2003 struct se_device *dev,
2004 unsigned char *buf,
2005 u32 pr_aptpl_buf_len)
2006{
Andy Grovere3d6f902011-07-19 08:55:10 +00002007 struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002008 struct file *file;
2009 struct iovec iov[1];
2010 mm_segment_t old_fs;
2011 int flags = O_RDWR | O_CREAT | O_TRUNC;
2012 char path[512];
2013 int ret;
2014
2015 memset(iov, 0, sizeof(struct iovec));
2016 memset(path, 0, 512);
2017
Dan Carpenter60d645a2011-06-15 10:03:05 -07002018 if (strlen(&wwn->unit_serial[0]) >= 512) {
Andy Grover6708bb22011-06-08 10:36:43 -07002019 pr_err("WWN value for struct se_device does not fit"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002020 " into path buffer\n");
Andy Grovere3d6f902011-07-19 08:55:10 +00002021 return -EMSGSIZE;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002022 }
2023
2024 snprintf(path, 512, "/var/target/pr/aptpl_%s", &wwn->unit_serial[0]);
2025 file = filp_open(path, flags, 0600);
2026 if (IS_ERR(file) || !file || !file->f_dentry) {
Andy Grover6708bb22011-06-08 10:36:43 -07002027 pr_err("filp_open(%s) for APTPL metadata"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002028 " failed\n", path);
Andy Grovere3d6f902011-07-19 08:55:10 +00002029 return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002030 }
2031
2032 iov[0].iov_base = &buf[0];
Andy Grover6708bb22011-06-08 10:36:43 -07002033 if (!pr_aptpl_buf_len)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002034 iov[0].iov_len = (strlen(&buf[0]) + 1); /* Add extra for NULL */
2035 else
2036 iov[0].iov_len = pr_aptpl_buf_len;
2037
2038 old_fs = get_fs();
2039 set_fs(get_ds());
2040 ret = vfs_writev(file, &iov[0], 1, &file->f_pos);
2041 set_fs(old_fs);
2042
2043 if (ret < 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07002044 pr_debug("Error writing APTPL metadata file: %s\n", path);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002045 filp_close(file, NULL);
Andy Grovere3d6f902011-07-19 08:55:10 +00002046 return -EIO;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002047 }
2048 filp_close(file, NULL);
2049
2050 return 0;
2051}
2052
2053static int core_scsi3_update_and_write_aptpl(
2054 struct se_device *dev,
2055 unsigned char *in_buf,
2056 u32 in_pr_aptpl_buf_len)
2057{
2058 unsigned char null_buf[64], *buf;
2059 u32 pr_aptpl_buf_len;
2060 int ret, clear_aptpl_metadata = 0;
2061 /*
2062 * Can be called with a NULL pointer from PROUT service action CLEAR
2063 */
Andy Grover6708bb22011-06-08 10:36:43 -07002064 if (!in_buf) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002065 memset(null_buf, 0, 64);
2066 buf = &null_buf[0];
2067 /*
2068 * This will clear the APTPL metadata to:
2069 * "No Registrations or Reservations" status
2070 */
2071 pr_aptpl_buf_len = 64;
2072 clear_aptpl_metadata = 1;
2073 } else {
2074 buf = in_buf;
2075 pr_aptpl_buf_len = in_pr_aptpl_buf_len;
2076 }
2077
2078 ret = core_scsi3_update_aptpl_buf(dev, buf, pr_aptpl_buf_len,
2079 clear_aptpl_metadata);
2080 if (ret != 0)
Andy Grovere3d6f902011-07-19 08:55:10 +00002081 return ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002082 /*
2083 * __core_scsi3_write_aptpl_to_file() will call strlen()
2084 * on the passed buf to determine pr_aptpl_buf_len.
2085 */
2086 ret = __core_scsi3_write_aptpl_to_file(dev, buf, 0);
2087 if (ret != 0)
Andy Grovere3d6f902011-07-19 08:55:10 +00002088 return ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002089
2090 return ret;
2091}
2092
2093static int core_scsi3_emulate_pro_register(
2094 struct se_cmd *cmd,
2095 u64 res_key,
2096 u64 sa_res_key,
2097 int aptpl,
2098 int all_tg_pt,
2099 int spec_i_pt,
2100 int ignore_key)
2101{
Andy Grovere3d6f902011-07-19 08:55:10 +00002102 struct se_session *se_sess = cmd->se_sess;
Andy Grover59511462011-07-19 10:26:37 +00002103 struct se_device *dev = cmd->se_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002104 struct se_dev_entry *se_deve;
Andy Grovere3d6f902011-07-19 08:55:10 +00002105 struct se_lun *se_lun = cmd->se_lun;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002106 struct se_portal_group *se_tpg;
2107 struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp, *pr_reg_e;
Andy Grovere3d6f902011-07-19 08:55:10 +00002108 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002109 /* Used for APTPL metadata w/ UNREGISTER */
2110 unsigned char *pr_aptpl_buf = NULL;
2111 unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
2112 int pr_holder = 0, ret = 0, type;
2113
Andy Grover6708bb22011-06-08 10:36:43 -07002114 if (!se_sess || !se_lun) {
2115 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002116 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2117 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002118 }
2119 se_tpg = se_sess->se_tpg;
2120 se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
2121
Andy Grovere3d6f902011-07-19 08:55:10 +00002122 if (se_tpg->se_tpg_tfo->sess_get_initiator_sid) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002123 memset(&isid_buf[0], 0, PR_REG_ISID_LEN);
Andy Grovere3d6f902011-07-19 08:55:10 +00002124 se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, &isid_buf[0],
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002125 PR_REG_ISID_LEN);
2126 isid_ptr = &isid_buf[0];
2127 }
2128 /*
2129 * Follow logic from spc4r17 Section 5.7.7, Register Behaviors Table 47
2130 */
2131 pr_reg_e = core_scsi3_locate_pr_reg(dev, se_sess->se_node_acl, se_sess);
Andy Grover6708bb22011-06-08 10:36:43 -07002132 if (!pr_reg_e) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002133 if (res_key) {
Andy Grover6708bb22011-06-08 10:36:43 -07002134 pr_warn("SPC-3 PR: Reservation Key non-zero"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002135 " for SA REGISTER, returning CONFLICT\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002136 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2137 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002138 }
2139 /*
2140 * Do nothing but return GOOD status.
2141 */
Andy Grover6708bb22011-06-08 10:36:43 -07002142 if (!sa_res_key)
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002143 return 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002144
Andy Grover6708bb22011-06-08 10:36:43 -07002145 if (!spec_i_pt) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002146 /*
2147 * Perform the Service Action REGISTER on the Initiator
2148 * Port Endpoint that the PRO was received from on the
2149 * Logical Unit of the SCSI device server.
2150 */
Andy Grover59511462011-07-19 10:26:37 +00002151 ret = core_scsi3_alloc_registration(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002152 se_sess->se_node_acl, se_deve, isid_ptr,
2153 sa_res_key, all_tg_pt, aptpl,
2154 ignore_key, 0);
2155 if (ret != 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07002156 pr_err("Unable to allocate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002157 " struct t10_pr_registration\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002158 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
2159 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002160 }
2161 } else {
2162 /*
2163 * Register both the Initiator port that received
2164 * PROUT SA REGISTER + SPEC_I_PT=1 and extract SCSI
2165 * TransportID from Parameter list and loop through
2166 * fabric dependent parameter list while calling
2167 * logic from of core_scsi3_alloc_registration() for
2168 * each TransportID provided SCSI Initiator Port/Device
2169 */
2170 ret = core_scsi3_decode_spec_i_port(cmd, se_tpg,
2171 isid_ptr, sa_res_key, all_tg_pt, aptpl);
2172 if (ret != 0)
2173 return ret;
2174 }
2175 /*
2176 * Nothing left to do for the APTPL=0 case.
2177 */
Andy Grover6708bb22011-06-08 10:36:43 -07002178 if (!aptpl) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002179 pr_tmpl->pr_aptpl_active = 0;
Andy Grover59511462011-07-19 10:26:37 +00002180 core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0);
Andy Grover6708bb22011-06-08 10:36:43 -07002181 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated for"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002182 " REGISTER\n");
2183 return 0;
2184 }
2185 /*
2186 * Locate the newly allocated local I_T Nexus *pr_reg, and
2187 * update the APTPL metadata information using its
2188 * preallocated *pr_reg->pr_aptpl_buf.
2189 */
Andy Grover59511462011-07-19 10:26:37 +00002190 pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002191 se_sess->se_node_acl, se_sess);
2192
Andy Grover59511462011-07-19 10:26:37 +00002193 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002194 &pr_reg->pr_aptpl_buf[0],
2195 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07002196 if (!ret) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002197 pr_tmpl->pr_aptpl_active = 1;
Andy Grover6708bb22011-06-08 10:36:43 -07002198 pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002199 }
2200
2201 core_scsi3_put_pr_reg(pr_reg);
2202 return ret;
2203 } else {
2204 /*
2205 * Locate the existing *pr_reg via struct se_node_acl pointers
2206 */
2207 pr_reg = pr_reg_e;
2208 type = pr_reg->pr_res_type;
2209
Andy Grover6708bb22011-06-08 10:36:43 -07002210 if (!ignore_key) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002211 if (res_key != pr_reg->pr_res_key) {
Andy Grover6708bb22011-06-08 10:36:43 -07002212 pr_err("SPC-3 PR REGISTER: Received"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002213 " res_key: 0x%016Lx does not match"
2214 " existing SA REGISTER res_key:"
2215 " 0x%016Lx\n", res_key,
2216 pr_reg->pr_res_key);
2217 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002218 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2219 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002220 }
2221 }
2222 if (spec_i_pt) {
Andy Grover6708bb22011-06-08 10:36:43 -07002223 pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002224 " set while sa_res_key=0\n");
2225 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002226 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
2227 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002228 }
2229 /*
2230 * An existing ALL_TG_PT=1 registration being released
2231 * must also set ALL_TG_PT=1 in the incoming PROUT.
2232 */
2233 if (pr_reg->pr_reg_all_tg_pt && !(all_tg_pt)) {
Andy Grover6708bb22011-06-08 10:36:43 -07002234 pr_err("SPC-3 PR UNREGISTER: ALL_TG_PT=1"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002235 " registration exists, but ALL_TG_PT=1 bit not"
2236 " present in received PROUT\n");
2237 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002238 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
2239 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002240 }
2241 /*
2242 * Allocate APTPL metadata buffer used for UNREGISTER ops
2243 */
2244 if (aptpl) {
2245 pr_aptpl_buf = kzalloc(pr_tmpl->pr_aptpl_buf_len,
2246 GFP_KERNEL);
Andy Grover6708bb22011-06-08 10:36:43 -07002247 if (!pr_aptpl_buf) {
2248 pr_err("Unable to allocate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002249 " pr_aptpl_buf\n");
2250 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002251 cmd->scsi_sense_reason =
2252 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2253 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002254 }
2255 }
2256 /*
2257 * sa_res_key=0 Unregister Reservation Key for registered I_T
2258 * Nexus sa_res_key=1 Change Reservation Key for registered I_T
2259 * Nexus.
2260 */
Andy Grover6708bb22011-06-08 10:36:43 -07002261 if (!sa_res_key) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002262 pr_holder = core_scsi3_check_implict_release(
Andy Grover59511462011-07-19 10:26:37 +00002263 cmd->se_dev, pr_reg);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002264 if (pr_holder < 0) {
2265 kfree(pr_aptpl_buf);
2266 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002267 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2268 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002269 }
2270
2271 spin_lock(&pr_tmpl->registration_lock);
2272 /*
2273 * Release all ALL_TG_PT=1 for the matching SCSI Initiator Port
2274 * and matching pr_res_key.
2275 */
2276 if (pr_reg->pr_reg_all_tg_pt) {
2277 list_for_each_entry_safe(pr_reg_p, pr_reg_tmp,
2278 &pr_tmpl->registration_list,
2279 pr_reg_list) {
2280
Andy Grover6708bb22011-06-08 10:36:43 -07002281 if (!pr_reg_p->pr_reg_all_tg_pt)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002282 continue;
2283
2284 if (pr_reg_p->pr_res_key != res_key)
2285 continue;
2286
2287 if (pr_reg == pr_reg_p)
2288 continue;
2289
2290 if (strcmp(pr_reg->pr_reg_nacl->initiatorname,
2291 pr_reg_p->pr_reg_nacl->initiatorname))
2292 continue;
2293
2294 __core_scsi3_free_registration(dev,
2295 pr_reg_p, NULL, 0);
2296 }
2297 }
2298 /*
2299 * Release the calling I_T Nexus registration now..
2300 */
Andy Grover59511462011-07-19 10:26:37 +00002301 __core_scsi3_free_registration(cmd->se_dev, pr_reg,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002302 NULL, 1);
2303 /*
2304 * From spc4r17, section 5.7.11.3 Unregistering
2305 *
2306 * If the persistent reservation is a registrants only
2307 * type, the device server shall establish a unit
2308 * attention condition for the initiator port associated
2309 * with every registered I_T nexus except for the I_T
2310 * nexus on which the PERSISTENT RESERVE OUT command was
2311 * received, with the additional sense code set to
2312 * RESERVATIONS RELEASED.
2313 */
2314 if (pr_holder &&
2315 ((type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) ||
2316 (type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY))) {
2317 list_for_each_entry(pr_reg_p,
2318 &pr_tmpl->registration_list,
2319 pr_reg_list) {
2320
2321 core_scsi3_ua_allocate(
2322 pr_reg_p->pr_reg_nacl,
2323 pr_reg_p->pr_res_mapped_lun,
2324 0x2A,
2325 ASCQ_2AH_RESERVATIONS_RELEASED);
2326 }
2327 }
2328 spin_unlock(&pr_tmpl->registration_lock);
2329
Andy Grover6708bb22011-06-08 10:36:43 -07002330 if (!aptpl) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002331 pr_tmpl->pr_aptpl_active = 0;
2332 core_scsi3_update_and_write_aptpl(dev, NULL, 0);
Andy Grover6708bb22011-06-08 10:36:43 -07002333 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002334 " for UNREGISTER\n");
2335 return 0;
2336 }
2337
2338 ret = core_scsi3_update_and_write_aptpl(dev,
2339 &pr_aptpl_buf[0],
2340 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07002341 if (!ret) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002342 pr_tmpl->pr_aptpl_active = 1;
Andy Grover6708bb22011-06-08 10:36:43 -07002343 pr_debug("SPC-3 PR: Set APTPL Bit Activated"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002344 " for UNREGISTER\n");
2345 }
2346
2347 kfree(pr_aptpl_buf);
2348 return ret;
2349 } else {
2350 /*
2351 * Increment PRgeneration counter for struct se_device"
2352 * upon a successful REGISTER, see spc4r17 section 6.3.2
2353 * READ_KEYS service action.
2354 */
2355 pr_reg->pr_res_generation = core_scsi3_pr_generation(
Andy Grover59511462011-07-19 10:26:37 +00002356 cmd->se_dev);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002357 pr_reg->pr_res_key = sa_res_key;
Andy Grover6708bb22011-06-08 10:36:43 -07002358 pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002359 " Key for %s to: 0x%016Lx PRgeneration:"
Andy Grovere3d6f902011-07-19 08:55:10 +00002360 " 0x%08x\n", cmd->se_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002361 (ignore_key) ? "_AND_IGNORE_EXISTING_KEY" : "",
2362 pr_reg->pr_reg_nacl->initiatorname,
2363 pr_reg->pr_res_key, pr_reg->pr_res_generation);
2364
Andy Grover6708bb22011-06-08 10:36:43 -07002365 if (!aptpl) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002366 pr_tmpl->pr_aptpl_active = 0;
2367 core_scsi3_update_and_write_aptpl(dev, NULL, 0);
2368 core_scsi3_put_pr_reg(pr_reg);
Andy Grover6708bb22011-06-08 10:36:43 -07002369 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002370 " for REGISTER\n");
2371 return 0;
2372 }
2373
2374 ret = core_scsi3_update_and_write_aptpl(dev,
2375 &pr_aptpl_buf[0],
2376 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07002377 if (!ret) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002378 pr_tmpl->pr_aptpl_active = 1;
Andy Grover6708bb22011-06-08 10:36:43 -07002379 pr_debug("SPC-3 PR: Set APTPL Bit Activated"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002380 " for REGISTER\n");
2381 }
2382
2383 kfree(pr_aptpl_buf);
2384 core_scsi3_put_pr_reg(pr_reg);
2385 }
2386 }
2387 return 0;
2388}
2389
2390unsigned char *core_scsi3_pr_dump_type(int type)
2391{
2392 switch (type) {
2393 case PR_TYPE_WRITE_EXCLUSIVE:
2394 return "Write Exclusive Access";
2395 case PR_TYPE_EXCLUSIVE_ACCESS:
2396 return "Exclusive Access";
2397 case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
2398 return "Write Exclusive Access, Registrants Only";
2399 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
2400 return "Exclusive Access, Registrants Only";
2401 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
2402 return "Write Exclusive Access, All Registrants";
2403 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
2404 return "Exclusive Access, All Registrants";
2405 default:
2406 break;
2407 }
2408
2409 return "Unknown SPC-3 PR Type";
2410}
2411
2412static int core_scsi3_pro_reserve(
2413 struct se_cmd *cmd,
2414 struct se_device *dev,
2415 int type,
2416 int scope,
2417 u64 res_key)
2418{
Andy Grovere3d6f902011-07-19 08:55:10 +00002419 struct se_session *se_sess = cmd->se_sess;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002420 struct se_dev_entry *se_deve;
Andy Grovere3d6f902011-07-19 08:55:10 +00002421 struct se_lun *se_lun = cmd->se_lun;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002422 struct se_portal_group *se_tpg;
2423 struct t10_pr_registration *pr_reg, *pr_res_holder;
Andy Grovere3d6f902011-07-19 08:55:10 +00002424 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002425 char i_buf[PR_REG_ISID_ID_LEN];
2426 int ret, prf_isid;
2427
2428 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
2429
Andy Grover6708bb22011-06-08 10:36:43 -07002430 if (!se_sess || !se_lun) {
2431 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002432 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2433 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002434 }
2435 se_tpg = se_sess->se_tpg;
2436 se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
2437 /*
2438 * Locate the existing *pr_reg via struct se_node_acl pointers
2439 */
Andy Grover59511462011-07-19 10:26:37 +00002440 pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002441 se_sess);
Andy Grover6708bb22011-06-08 10:36:43 -07002442 if (!pr_reg) {
2443 pr_err("SPC-3 PR: Unable to locate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002444 " PR_REGISTERED *pr_reg for RESERVE\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002445 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2446 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002447 }
2448 /*
2449 * From spc4r17 Section 5.7.9: Reserving:
2450 *
2451 * An application client creates a persistent reservation by issuing
2452 * a PERSISTENT RESERVE OUT command with RESERVE service action through
2453 * a registered I_T nexus with the following parameters:
2454 * a) RESERVATION KEY set to the value of the reservation key that is
2455 * registered with the logical unit for the I_T nexus; and
2456 */
2457 if (res_key != pr_reg->pr_res_key) {
Andy Grover6708bb22011-06-08 10:36:43 -07002458 pr_err("SPC-3 PR RESERVE: Received res_key: 0x%016Lx"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002459 " does not match existing SA REGISTER res_key:"
2460 " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
2461 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002462 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2463 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002464 }
2465 /*
2466 * From spc4r17 Section 5.7.9: Reserving:
2467 *
2468 * From above:
2469 * b) TYPE field and SCOPE field set to the persistent reservation
2470 * being created.
2471 *
2472 * Only one persistent reservation is allowed at a time per logical unit
2473 * and that persistent reservation has a scope of LU_SCOPE.
2474 */
2475 if (scope != PR_SCOPE_LU_SCOPE) {
Andy Grover6708bb22011-06-08 10:36:43 -07002476 pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002477 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002478 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
2479 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002480 }
2481 /*
2482 * See if we have an existing PR reservation holder pointer at
2483 * struct se_device->dev_pr_res_holder in the form struct t10_pr_registration
2484 * *pr_res_holder.
2485 */
2486 spin_lock(&dev->dev_reservation_lock);
2487 pr_res_holder = dev->dev_pr_res_holder;
2488 if ((pr_res_holder)) {
2489 /*
2490 * From spc4r17 Section 5.7.9: Reserving:
2491 *
2492 * If the device server receives a PERSISTENT RESERVE OUT
2493 * command from an I_T nexus other than a persistent reservation
2494 * holder (see 5.7.10) that attempts to create a persistent
2495 * reservation when a persistent reservation already exists for
2496 * the logical unit, then the command shall be completed with
2497 * RESERVATION CONFLICT status.
2498 */
2499 if (pr_res_holder != pr_reg) {
2500 struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
Andy Grover6708bb22011-06-08 10:36:43 -07002501 pr_err("SPC-3 PR: Attempted RESERVE from"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002502 " [%s]: %s while reservation already held by"
2503 " [%s]: %s, returning RESERVATION_CONFLICT\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00002504 cmd->se_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002505 se_sess->se_node_acl->initiatorname,
Andy Grovere3d6f902011-07-19 08:55:10 +00002506 pr_res_nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002507 pr_res_holder->pr_reg_nacl->initiatorname);
2508
2509 spin_unlock(&dev->dev_reservation_lock);
2510 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002511 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2512 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002513 }
2514 /*
2515 * From spc4r17 Section 5.7.9: Reserving:
2516 *
2517 * If a persistent reservation holder attempts to modify the
2518 * type or scope of an existing persistent reservation, the
2519 * command shall be completed with RESERVATION CONFLICT status.
2520 */
2521 if ((pr_res_holder->pr_res_type != type) ||
2522 (pr_res_holder->pr_res_scope != scope)) {
2523 struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
Andy Grover6708bb22011-06-08 10:36:43 -07002524 pr_err("SPC-3 PR: Attempted RESERVE from"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002525 " [%s]: %s trying to change TYPE and/or SCOPE,"
2526 " while reservation already held by [%s]: %s,"
2527 " returning RESERVATION_CONFLICT\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00002528 cmd->se_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002529 se_sess->se_node_acl->initiatorname,
Andy Grovere3d6f902011-07-19 08:55:10 +00002530 pr_res_nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002531 pr_res_holder->pr_reg_nacl->initiatorname);
2532
2533 spin_unlock(&dev->dev_reservation_lock);
2534 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002535 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2536 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002537 }
2538 /*
2539 * From spc4r17 Section 5.7.9: Reserving:
2540 *
2541 * If the device server receives a PERSISTENT RESERVE OUT
2542 * command with RESERVE service action where the TYPE field and
2543 * the SCOPE field contain the same values as the existing type
2544 * and scope from a persistent reservation holder, it shall not
2545 * make any change to the existing persistent reservation and
2546 * shall completethe command with GOOD status.
2547 */
2548 spin_unlock(&dev->dev_reservation_lock);
2549 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002550 return 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002551 }
2552 /*
2553 * Otherwise, our *pr_reg becomes the PR reservation holder for said
2554 * TYPE/SCOPE. Also set the received scope and type in *pr_reg.
2555 */
2556 pr_reg->pr_res_scope = scope;
2557 pr_reg->pr_res_type = type;
2558 pr_reg->pr_res_holder = 1;
2559 dev->dev_pr_res_holder = pr_reg;
2560 prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
2561 PR_REG_ISID_ID_LEN);
2562
Andy Grover6708bb22011-06-08 10:36:43 -07002563 pr_debug("SPC-3 PR [%s] Service Action: RESERVE created new"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002564 " reservation holder TYPE: %s ALL_TG_PT: %d\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00002565 cmd->se_tfo->get_fabric_name(), core_scsi3_pr_dump_type(type),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002566 (pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
Andy Grover6708bb22011-06-08 10:36:43 -07002567 pr_debug("SPC-3 PR [%s] RESERVE Node: %s%s\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00002568 cmd->se_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002569 se_sess->se_node_acl->initiatorname,
2570 (prf_isid) ? &i_buf[0] : "");
2571 spin_unlock(&dev->dev_reservation_lock);
2572
2573 if (pr_tmpl->pr_aptpl_active) {
Andy Grover59511462011-07-19 10:26:37 +00002574 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002575 &pr_reg->pr_aptpl_buf[0],
2576 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07002577 if (!ret)
2578 pr_debug("SPC-3 PR: Updated APTPL metadata"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002579 " for RESERVE\n");
2580 }
2581
2582 core_scsi3_put_pr_reg(pr_reg);
2583 return 0;
2584}
2585
2586static int core_scsi3_emulate_pro_reserve(
2587 struct se_cmd *cmd,
2588 int type,
2589 int scope,
2590 u64 res_key)
2591{
2592 struct se_device *dev = cmd->se_dev;
2593 int ret = 0;
2594
2595 switch (type) {
2596 case PR_TYPE_WRITE_EXCLUSIVE:
2597 case PR_TYPE_EXCLUSIVE_ACCESS:
2598 case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
2599 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
2600 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
2601 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
2602 ret = core_scsi3_pro_reserve(cmd, dev, type, scope, res_key);
2603 break;
2604 default:
Andy Grover6708bb22011-06-08 10:36:43 -07002605 pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002606 " 0x%02x\n", type);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002607 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
2608 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002609 }
2610
2611 return ret;
2612}
2613
2614/*
2615 * Called with struct se_device->dev_reservation_lock held.
2616 */
2617static void __core_scsi3_complete_pro_release(
2618 struct se_device *dev,
2619 struct se_node_acl *se_nacl,
2620 struct t10_pr_registration *pr_reg,
2621 int explict)
2622{
2623 struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo;
2624 char i_buf[PR_REG_ISID_ID_LEN];
2625 int prf_isid;
2626
2627 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
2628 prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
2629 PR_REG_ISID_ID_LEN);
2630 /*
2631 * Go ahead and release the current PR reservation holder.
2632 */
2633 dev->dev_pr_res_holder = NULL;
2634
Andy Grover6708bb22011-06-08 10:36:43 -07002635 pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002636 " reservation holder TYPE: %s ALL_TG_PT: %d\n",
2637 tfo->get_fabric_name(), (explict) ? "explict" : "implict",
2638 core_scsi3_pr_dump_type(pr_reg->pr_res_type),
2639 (pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
Andy Grover6708bb22011-06-08 10:36:43 -07002640 pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n",
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002641 tfo->get_fabric_name(), se_nacl->initiatorname,
2642 (prf_isid) ? &i_buf[0] : "");
2643 /*
2644 * Clear TYPE and SCOPE for the next PROUT Service Action: RESERVE
2645 */
2646 pr_reg->pr_res_holder = pr_reg->pr_res_type = pr_reg->pr_res_scope = 0;
2647}
2648
2649static int core_scsi3_emulate_pro_release(
2650 struct se_cmd *cmd,
2651 int type,
2652 int scope,
2653 u64 res_key)
2654{
2655 struct se_device *dev = cmd->se_dev;
Andy Grovere3d6f902011-07-19 08:55:10 +00002656 struct se_session *se_sess = cmd->se_sess;
2657 struct se_lun *se_lun = cmd->se_lun;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002658 struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder;
Andy Grovere3d6f902011-07-19 08:55:10 +00002659 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002660 int ret, all_reg = 0;
2661
Andy Grover6708bb22011-06-08 10:36:43 -07002662 if (!se_sess || !se_lun) {
2663 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002664 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2665 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002666 }
2667 /*
2668 * Locate the existing *pr_reg via struct se_node_acl pointers
2669 */
2670 pr_reg = core_scsi3_locate_pr_reg(dev, se_sess->se_node_acl, se_sess);
Andy Grover6708bb22011-06-08 10:36:43 -07002671 if (!pr_reg) {
2672 pr_err("SPC-3 PR: Unable to locate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002673 " PR_REGISTERED *pr_reg for RELEASE\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002674 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2675 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002676 }
2677 /*
2678 * From spc4r17 Section 5.7.11.2 Releasing:
2679 *
2680 * If there is no persistent reservation or in response to a persistent
2681 * reservation release request from a registered I_T nexus that is not a
2682 * persistent reservation holder (see 5.7.10), the device server shall
2683 * do the following:
2684 *
2685 * a) Not release the persistent reservation, if any;
2686 * b) Not remove any registrations; and
2687 * c) Complete the command with GOOD status.
2688 */
2689 spin_lock(&dev->dev_reservation_lock);
2690 pr_res_holder = dev->dev_pr_res_holder;
Andy Grover6708bb22011-06-08 10:36:43 -07002691 if (!pr_res_holder) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002692 /*
2693 * No persistent reservation, return GOOD status.
2694 */
2695 spin_unlock(&dev->dev_reservation_lock);
2696 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002697 return 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002698 }
2699 if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
2700 (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))
2701 all_reg = 1;
2702
2703 if ((all_reg == 0) && (pr_res_holder != pr_reg)) {
2704 /*
2705 * Non 'All Registrants' PR Type cases..
2706 * Release request from a registered I_T nexus that is not a
2707 * persistent reservation holder. return GOOD status.
2708 */
2709 spin_unlock(&dev->dev_reservation_lock);
2710 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002711 return 0;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002712 }
2713 /*
2714 * From spc4r17 Section 5.7.11.2 Releasing:
2715 *
2716 * Only the persistent reservation holder (see 5.7.10) is allowed to
2717 * release a persistent reservation.
2718 *
2719 * An application client releases the persistent reservation by issuing
2720 * a PERSISTENT RESERVE OUT command with RELEASE service action through
2721 * an I_T nexus that is a persistent reservation holder with the
2722 * following parameters:
2723 *
2724 * a) RESERVATION KEY field set to the value of the reservation key
2725 * that is registered with the logical unit for the I_T nexus;
2726 */
2727 if (res_key != pr_reg->pr_res_key) {
Andy Grover6708bb22011-06-08 10:36:43 -07002728 pr_err("SPC-3 PR RELEASE: Received res_key: 0x%016Lx"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002729 " does not match existing SA REGISTER res_key:"
2730 " 0x%016Lx\n", res_key, pr_reg->pr_res_key);
2731 spin_unlock(&dev->dev_reservation_lock);
2732 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002733 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2734 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002735 }
2736 /*
2737 * From spc4r17 Section 5.7.11.2 Releasing and above:
2738 *
2739 * b) TYPE field and SCOPE field set to match the persistent
2740 * reservation being released.
2741 */
2742 if ((pr_res_holder->pr_res_type != type) ||
2743 (pr_res_holder->pr_res_scope != scope)) {
2744 struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
Andy Grover6708bb22011-06-08 10:36:43 -07002745 pr_err("SPC-3 PR RELEASE: Attempted to release"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002746 " reservation from [%s]: %s with different TYPE "
2747 "and/or SCOPE while reservation already held by"
2748 " [%s]: %s, returning RESERVATION_CONFLICT\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00002749 cmd->se_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002750 se_sess->se_node_acl->initiatorname,
Andy Grovere3d6f902011-07-19 08:55:10 +00002751 pr_res_nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002752 pr_res_holder->pr_reg_nacl->initiatorname);
2753
2754 spin_unlock(&dev->dev_reservation_lock);
2755 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002756 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2757 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002758 }
2759 /*
2760 * In response to a persistent reservation release request from the
2761 * persistent reservation holder the device server shall perform a
2762 * release by doing the following as an uninterrupted series of actions:
2763 * a) Release the persistent reservation;
2764 * b) Not remove any registration(s);
2765 * c) If the released persistent reservation is a registrants only type
2766 * or all registrants type persistent reservation,
2767 * the device server shall establish a unit attention condition for
2768 * the initiator port associated with every regis-
2769 * tered I_T nexus other than I_T nexus on which the PERSISTENT
2770 * RESERVE OUT command with RELEASE service action was received,
2771 * with the additional sense code set to RESERVATIONS RELEASED; and
2772 * d) If the persistent reservation is of any other type, the device
2773 * server shall not establish a unit attention condition.
2774 */
2775 __core_scsi3_complete_pro_release(dev, se_sess->se_node_acl,
2776 pr_reg, 1);
2777
2778 spin_unlock(&dev->dev_reservation_lock);
2779
2780 if ((type != PR_TYPE_WRITE_EXCLUSIVE_REGONLY) &&
2781 (type != PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) &&
2782 (type != PR_TYPE_WRITE_EXCLUSIVE_ALLREG) &&
2783 (type != PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
2784 /*
2785 * If no UNIT ATTENTION conditions will be established for
2786 * PR_TYPE_WRITE_EXCLUSIVE or PR_TYPE_EXCLUSIVE_ACCESS
2787 * go ahead and check for APTPL=1 update+write below
2788 */
2789 goto write_aptpl;
2790 }
2791
2792 spin_lock(&pr_tmpl->registration_lock);
2793 list_for_each_entry(pr_reg_p, &pr_tmpl->registration_list,
2794 pr_reg_list) {
2795 /*
2796 * Do not establish a UNIT ATTENTION condition
2797 * for the calling I_T Nexus
2798 */
2799 if (pr_reg_p == pr_reg)
2800 continue;
2801
2802 core_scsi3_ua_allocate(pr_reg_p->pr_reg_nacl,
2803 pr_reg_p->pr_res_mapped_lun,
2804 0x2A, ASCQ_2AH_RESERVATIONS_RELEASED);
2805 }
2806 spin_unlock(&pr_tmpl->registration_lock);
2807
2808write_aptpl:
2809 if (pr_tmpl->pr_aptpl_active) {
Andy Grover59511462011-07-19 10:26:37 +00002810 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002811 &pr_reg->pr_aptpl_buf[0],
2812 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07002813 if (!ret)
2814 pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002815 }
2816
2817 core_scsi3_put_pr_reg(pr_reg);
2818 return 0;
2819}
2820
2821static int core_scsi3_emulate_pro_clear(
2822 struct se_cmd *cmd,
2823 u64 res_key)
2824{
2825 struct se_device *dev = cmd->se_dev;
2826 struct se_node_acl *pr_reg_nacl;
Andy Grovere3d6f902011-07-19 08:55:10 +00002827 struct se_session *se_sess = cmd->se_sess;
2828 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002829 struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
2830 u32 pr_res_mapped_lun = 0;
2831 int calling_it_nexus = 0;
2832 /*
2833 * Locate the existing *pr_reg via struct se_node_acl pointers
2834 */
Andy Grover59511462011-07-19 10:26:37 +00002835 pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002836 se_sess->se_node_acl, se_sess);
Andy Grover6708bb22011-06-08 10:36:43 -07002837 if (!pr_reg_n) {
2838 pr_err("SPC-3 PR: Unable to locate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002839 " PR_REGISTERED *pr_reg for CLEAR\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002840 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
2841 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002842 }
2843 /*
2844 * From spc4r17 section 5.7.11.6, Clearing:
2845 *
2846 * Any application client may release the persistent reservation and
2847 * remove all registrations from a device server by issuing a
2848 * PERSISTENT RESERVE OUT command with CLEAR service action through a
2849 * registered I_T nexus with the following parameter:
2850 *
2851 * a) RESERVATION KEY field set to the value of the reservation key
2852 * that is registered with the logical unit for the I_T nexus.
2853 */
2854 if (res_key != pr_reg_n->pr_res_key) {
Andy Grover6708bb22011-06-08 10:36:43 -07002855 pr_err("SPC-3 PR REGISTER: Received"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002856 " res_key: 0x%016Lx does not match"
2857 " existing SA REGISTER res_key:"
2858 " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key);
2859 core_scsi3_put_pr_reg(pr_reg_n);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07002860 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
2861 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002862 }
2863 /*
2864 * a) Release the persistent reservation, if any;
2865 */
2866 spin_lock(&dev->dev_reservation_lock);
2867 pr_res_holder = dev->dev_pr_res_holder;
2868 if (pr_res_holder) {
2869 struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl;
2870 __core_scsi3_complete_pro_release(dev, pr_res_nacl,
2871 pr_res_holder, 0);
2872 }
2873 spin_unlock(&dev->dev_reservation_lock);
2874 /*
2875 * b) Remove all registration(s) (see spc4r17 5.7.7);
2876 */
2877 spin_lock(&pr_tmpl->registration_lock);
2878 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
2879 &pr_tmpl->registration_list, pr_reg_list) {
2880
2881 calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
2882 pr_reg_nacl = pr_reg->pr_reg_nacl;
2883 pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
2884 __core_scsi3_free_registration(dev, pr_reg, NULL,
2885 calling_it_nexus);
2886 /*
2887 * e) Establish a unit attention condition for the initiator
2888 * port associated with every registered I_T nexus other
2889 * than the I_T nexus on which the PERSISTENT RESERVE OUT
2890 * command with CLEAR service action was received, with the
2891 * additional sense code set to RESERVATIONS PREEMPTED.
2892 */
Andy Grover6708bb22011-06-08 10:36:43 -07002893 if (!calling_it_nexus)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002894 core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun,
2895 0x2A, ASCQ_2AH_RESERVATIONS_PREEMPTED);
2896 }
2897 spin_unlock(&pr_tmpl->registration_lock);
2898
Andy Grover6708bb22011-06-08 10:36:43 -07002899 pr_debug("SPC-3 PR [%s] Service Action: CLEAR complete\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00002900 cmd->se_tfo->get_fabric_name());
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002901
2902 if (pr_tmpl->pr_aptpl_active) {
Andy Grover59511462011-07-19 10:26:37 +00002903 core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0);
Andy Grover6708bb22011-06-08 10:36:43 -07002904 pr_debug("SPC-3 PR: Updated APTPL metadata"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002905 " for CLEAR\n");
2906 }
2907
2908 core_scsi3_pr_generation(dev);
2909 return 0;
2910}
2911
2912/*
2913 * Called with struct se_device->dev_reservation_lock held.
2914 */
2915static void __core_scsi3_complete_pro_preempt(
2916 struct se_device *dev,
2917 struct t10_pr_registration *pr_reg,
2918 struct list_head *preempt_and_abort_list,
2919 int type,
2920 int scope,
2921 int abort)
2922{
2923 struct se_node_acl *nacl = pr_reg->pr_reg_nacl;
2924 struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo;
2925 char i_buf[PR_REG_ISID_ID_LEN];
2926 int prf_isid;
2927
2928 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
2929 prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
2930 PR_REG_ISID_ID_LEN);
2931 /*
2932 * Do an implict RELEASE of the existing reservation.
2933 */
2934 if (dev->dev_pr_res_holder)
2935 __core_scsi3_complete_pro_release(dev, nacl,
2936 dev->dev_pr_res_holder, 0);
2937
2938 dev->dev_pr_res_holder = pr_reg;
2939 pr_reg->pr_res_holder = 1;
2940 pr_reg->pr_res_type = type;
2941 pr_reg->pr_res_scope = scope;
2942
Andy Grover6708bb22011-06-08 10:36:43 -07002943 pr_debug("SPC-3 PR [%s] Service Action: PREEMPT%s created new"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002944 " reservation holder TYPE: %s ALL_TG_PT: %d\n",
2945 tfo->get_fabric_name(), (abort) ? "_AND_ABORT" : "",
2946 core_scsi3_pr_dump_type(type),
2947 (pr_reg->pr_reg_all_tg_pt) ? 1 : 0);
Andy Grover6708bb22011-06-08 10:36:43 -07002948 pr_debug("SPC-3 PR [%s] PREEMPT%s from Node: %s%s\n",
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002949 tfo->get_fabric_name(), (abort) ? "_AND_ABORT" : "",
2950 nacl->initiatorname, (prf_isid) ? &i_buf[0] : "");
2951 /*
2952 * For PREEMPT_AND_ABORT, add the preempting reservation's
2953 * struct t10_pr_registration to the list that will be compared
2954 * against received CDBs..
2955 */
2956 if (preempt_and_abort_list)
2957 list_add_tail(&pr_reg->pr_reg_abort_list,
2958 preempt_and_abort_list);
2959}
2960
2961static void core_scsi3_release_preempt_and_abort(
2962 struct list_head *preempt_and_abort_list,
2963 struct t10_pr_registration *pr_reg_holder)
2964{
2965 struct t10_pr_registration *pr_reg, *pr_reg_tmp;
2966
2967 list_for_each_entry_safe(pr_reg, pr_reg_tmp, preempt_and_abort_list,
2968 pr_reg_abort_list) {
2969
2970 list_del(&pr_reg->pr_reg_abort_list);
2971 if (pr_reg_holder == pr_reg)
2972 continue;
2973 if (pr_reg->pr_res_holder) {
Andy Grover6708bb22011-06-08 10:36:43 -07002974 pr_warn("pr_reg->pr_res_holder still set\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002975 continue;
2976 }
2977
2978 pr_reg->pr_reg_deve = NULL;
2979 pr_reg->pr_reg_nacl = NULL;
2980 kfree(pr_reg->pr_aptpl_buf);
2981 kmem_cache_free(t10_pr_reg_cache, pr_reg);
2982 }
2983}
2984
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002985static int core_scsi3_pro_preempt(
2986 struct se_cmd *cmd,
2987 int type,
2988 int scope,
2989 u64 res_key,
2990 u64 sa_res_key,
2991 int abort)
2992{
Andy Grover59511462011-07-19 10:26:37 +00002993 struct se_device *dev = cmd->se_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002994 struct se_dev_entry *se_deve;
2995 struct se_node_acl *pr_reg_nacl;
Andy Grovere3d6f902011-07-19 08:55:10 +00002996 struct se_session *se_sess = cmd->se_sess;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08002997 struct list_head preempt_and_abort_list;
2998 struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
Andy Grovere3d6f902011-07-19 08:55:10 +00002999 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003000 u32 pr_res_mapped_lun = 0;
3001 int all_reg = 0, calling_it_nexus = 0, released_regs = 0;
3002 int prh_type = 0, prh_scope = 0, ret;
3003
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003004 if (!se_sess) {
3005 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3006 return -EINVAL;
3007 }
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003008
3009 se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
Andy Grover59511462011-07-19 10:26:37 +00003010 pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003011 se_sess);
Andy Grover6708bb22011-06-08 10:36:43 -07003012 if (!pr_reg_n) {
3013 pr_err("SPC-3 PR: Unable to locate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003014 " PR_REGISTERED *pr_reg for PREEMPT%s\n",
3015 (abort) ? "_AND_ABORT" : "");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003016 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
3017 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003018 }
3019 if (pr_reg_n->pr_res_key != res_key) {
3020 core_scsi3_put_pr_reg(pr_reg_n);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003021 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
3022 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003023 }
3024 if (scope != PR_SCOPE_LU_SCOPE) {
Andy Grover6708bb22011-06-08 10:36:43 -07003025 pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003026 core_scsi3_put_pr_reg(pr_reg_n);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003027 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3028 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003029 }
3030 INIT_LIST_HEAD(&preempt_and_abort_list);
3031
3032 spin_lock(&dev->dev_reservation_lock);
3033 pr_res_holder = dev->dev_pr_res_holder;
3034 if (pr_res_holder &&
3035 ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
3036 (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)))
3037 all_reg = 1;
3038
Andy Grover6708bb22011-06-08 10:36:43 -07003039 if (!all_reg && !sa_res_key) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003040 spin_unlock(&dev->dev_reservation_lock);
3041 core_scsi3_put_pr_reg(pr_reg_n);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003042 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3043 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003044 }
3045 /*
3046 * From spc4r17, section 5.7.11.4.4 Removing Registrations:
3047 *
3048 * If the SERVICE ACTION RESERVATION KEY field does not identify a
3049 * persistent reservation holder or there is no persistent reservation
3050 * holder (i.e., there is no persistent reservation), then the device
3051 * server shall perform a preempt by doing the following in an
3052 * uninterrupted series of actions. (See below..)
3053 */
Andy Grover6708bb22011-06-08 10:36:43 -07003054 if (!pr_res_holder || (pr_res_holder->pr_res_key != sa_res_key)) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003055 /*
3056 * No existing or SA Reservation Key matching reservations..
3057 *
3058 * PROUT SA PREEMPT with All Registrant type reservations are
3059 * allowed to be processed without a matching SA Reservation Key
3060 */
3061 spin_lock(&pr_tmpl->registration_lock);
3062 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
3063 &pr_tmpl->registration_list, pr_reg_list) {
3064 /*
3065 * Removing of registrations in non all registrants
3066 * type reservations without a matching SA reservation
3067 * key.
3068 *
3069 * a) Remove the registrations for all I_T nexuses
3070 * specified by the SERVICE ACTION RESERVATION KEY
3071 * field;
3072 * b) Ignore the contents of the SCOPE and TYPE fields;
3073 * c) Process tasks as defined in 5.7.1; and
3074 * d) Establish a unit attention condition for the
3075 * initiator port associated with every I_T nexus
3076 * that lost its registration other than the I_T
3077 * nexus on which the PERSISTENT RESERVE OUT command
3078 * was received, with the additional sense code set
3079 * to REGISTRATIONS PREEMPTED.
3080 */
Andy Grover6708bb22011-06-08 10:36:43 -07003081 if (!all_reg) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003082 if (pr_reg->pr_res_key != sa_res_key)
3083 continue;
3084
3085 calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
3086 pr_reg_nacl = pr_reg->pr_reg_nacl;
3087 pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
3088 __core_scsi3_free_registration(dev, pr_reg,
3089 (abort) ? &preempt_and_abort_list :
3090 NULL, calling_it_nexus);
3091 released_regs++;
3092 } else {
3093 /*
3094 * Case for any existing all registrants type
3095 * reservation, follow logic in spc4r17 section
3096 * 5.7.11.4 Preempting, Table 52 and Figure 7.
3097 *
3098 * For a ZERO SA Reservation key, release
3099 * all other registrations and do an implict
3100 * release of active persistent reservation.
3101 *
3102 * For a non-ZERO SA Reservation key, only
3103 * release the matching reservation key from
3104 * registrations.
3105 */
3106 if ((sa_res_key) &&
3107 (pr_reg->pr_res_key != sa_res_key))
3108 continue;
3109
3110 calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
3111 if (calling_it_nexus)
3112 continue;
3113
3114 pr_reg_nacl = pr_reg->pr_reg_nacl;
3115 pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
3116 __core_scsi3_free_registration(dev, pr_reg,
3117 (abort) ? &preempt_and_abort_list :
3118 NULL, 0);
3119 released_regs++;
3120 }
Andy Grover6708bb22011-06-08 10:36:43 -07003121 if (!calling_it_nexus)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003122 core_scsi3_ua_allocate(pr_reg_nacl,
3123 pr_res_mapped_lun, 0x2A,
Marco Sanvido9e08e342012-01-03 17:12:57 -08003124 ASCQ_2AH_REGISTRATIONS_PREEMPTED);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003125 }
3126 spin_unlock(&pr_tmpl->registration_lock);
3127 /*
3128 * If a PERSISTENT RESERVE OUT with a PREEMPT service action or
3129 * a PREEMPT AND ABORT service action sets the SERVICE ACTION
3130 * RESERVATION KEY field to a value that does not match any
3131 * registered reservation key, then the device server shall
3132 * complete the command with RESERVATION CONFLICT status.
3133 */
Andy Grover6708bb22011-06-08 10:36:43 -07003134 if (!released_regs) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003135 spin_unlock(&dev->dev_reservation_lock);
3136 core_scsi3_put_pr_reg(pr_reg_n);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003137 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
3138 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003139 }
3140 /*
3141 * For an existing all registrants type reservation
3142 * with a zero SA rservation key, preempt the existing
3143 * reservation with the new PR type and scope.
3144 */
3145 if (pr_res_holder && all_reg && !(sa_res_key)) {
3146 __core_scsi3_complete_pro_preempt(dev, pr_reg_n,
3147 (abort) ? &preempt_and_abort_list : NULL,
3148 type, scope, abort);
3149
3150 if (abort)
3151 core_scsi3_release_preempt_and_abort(
3152 &preempt_and_abort_list, pr_reg_n);
3153 }
3154 spin_unlock(&dev->dev_reservation_lock);
3155
3156 if (pr_tmpl->pr_aptpl_active) {
Andy Grover59511462011-07-19 10:26:37 +00003157 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003158 &pr_reg_n->pr_aptpl_buf[0],
3159 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07003160 if (!ret)
3161 pr_debug("SPC-3 PR: Updated APTPL"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003162 " metadata for PREEMPT%s\n", (abort) ?
3163 "_AND_ABORT" : "");
3164 }
3165
3166 core_scsi3_put_pr_reg(pr_reg_n);
Andy Grover59511462011-07-19 10:26:37 +00003167 core_scsi3_pr_generation(cmd->se_dev);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003168 return 0;
3169 }
3170 /*
3171 * The PREEMPTing SA reservation key matches that of the
3172 * existing persistent reservation, first, we check if
3173 * we are preempting our own reservation.
3174 * From spc4r17, section 5.7.11.4.3 Preempting
3175 * persistent reservations and registration handling
3176 *
3177 * If an all registrants persistent reservation is not
3178 * present, it is not an error for the persistent
3179 * reservation holder to preempt itself (i.e., a
3180 * PERSISTENT RESERVE OUT with a PREEMPT service action
3181 * or a PREEMPT AND ABORT service action with the
3182 * SERVICE ACTION RESERVATION KEY value equal to the
3183 * persistent reservation holder's reservation key that
3184 * is received from the persistent reservation holder).
3185 * In that case, the device server shall establish the
3186 * new persistent reservation and maintain the
3187 * registration.
3188 */
3189 prh_type = pr_res_holder->pr_res_type;
3190 prh_scope = pr_res_holder->pr_res_scope;
3191 /*
3192 * If the SERVICE ACTION RESERVATION KEY field identifies a
3193 * persistent reservation holder (see 5.7.10), the device
3194 * server shall perform a preempt by doing the following as
3195 * an uninterrupted series of actions:
3196 *
3197 * a) Release the persistent reservation for the holder
3198 * identified by the SERVICE ACTION RESERVATION KEY field;
3199 */
3200 if (pr_reg_n != pr_res_holder)
3201 __core_scsi3_complete_pro_release(dev,
3202 pr_res_holder->pr_reg_nacl,
3203 dev->dev_pr_res_holder, 0);
3204 /*
3205 * b) Remove the registrations for all I_T nexuses identified
3206 * by the SERVICE ACTION RESERVATION KEY field, except the
3207 * I_T nexus that is being used for the PERSISTENT RESERVE
3208 * OUT command. If an all registrants persistent reservation
3209 * is present and the SERVICE ACTION RESERVATION KEY field
3210 * is set to zero, then all registrations shall be removed
3211 * except for that of the I_T nexus that is being used for
3212 * the PERSISTENT RESERVE OUT command;
3213 */
3214 spin_lock(&pr_tmpl->registration_lock);
3215 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
3216 &pr_tmpl->registration_list, pr_reg_list) {
3217
3218 calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
3219 if (calling_it_nexus)
3220 continue;
3221
3222 if (pr_reg->pr_res_key != sa_res_key)
3223 continue;
3224
3225 pr_reg_nacl = pr_reg->pr_reg_nacl;
3226 pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
3227 __core_scsi3_free_registration(dev, pr_reg,
3228 (abort) ? &preempt_and_abort_list : NULL,
3229 calling_it_nexus);
3230 /*
3231 * e) Establish a unit attention condition for the initiator
3232 * port associated with every I_T nexus that lost its
3233 * persistent reservation and/or registration, with the
3234 * additional sense code set to REGISTRATIONS PREEMPTED;
3235 */
3236 core_scsi3_ua_allocate(pr_reg_nacl, pr_res_mapped_lun, 0x2A,
Marco Sanvido9e08e342012-01-03 17:12:57 -08003237 ASCQ_2AH_REGISTRATIONS_PREEMPTED);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003238 }
3239 spin_unlock(&pr_tmpl->registration_lock);
3240 /*
3241 * c) Establish a persistent reservation for the preempting
3242 * I_T nexus using the contents of the SCOPE and TYPE fields;
3243 */
3244 __core_scsi3_complete_pro_preempt(dev, pr_reg_n,
3245 (abort) ? &preempt_and_abort_list : NULL,
3246 type, scope, abort);
3247 /*
3248 * d) Process tasks as defined in 5.7.1;
3249 * e) See above..
3250 * f) If the type or scope has changed, then for every I_T nexus
3251 * whose reservation key was not removed, except for the I_T
3252 * nexus on which the PERSISTENT RESERVE OUT command was
3253 * received, the device server shall establish a unit
3254 * attention condition for the initiator port associated with
3255 * that I_T nexus, with the additional sense code set to
3256 * RESERVATIONS RELEASED. If the type or scope have not
3257 * changed, then no unit attention condition(s) shall be
3258 * established for this reason.
3259 */
3260 if ((prh_type != type) || (prh_scope != scope)) {
3261 spin_lock(&pr_tmpl->registration_lock);
3262 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
3263 &pr_tmpl->registration_list, pr_reg_list) {
3264
3265 calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
3266 if (calling_it_nexus)
3267 continue;
3268
3269 core_scsi3_ua_allocate(pr_reg->pr_reg_nacl,
3270 pr_reg->pr_res_mapped_lun, 0x2A,
3271 ASCQ_2AH_RESERVATIONS_RELEASED);
3272 }
3273 spin_unlock(&pr_tmpl->registration_lock);
3274 }
3275 spin_unlock(&dev->dev_reservation_lock);
3276 /*
3277 * Call LUN_RESET logic upon list of struct t10_pr_registration,
3278 * All received CDBs for the matching existing reservation and
3279 * registrations undergo ABORT_TASK logic.
3280 *
3281 * From there, core_scsi3_release_preempt_and_abort() will
3282 * release every registration in the list (which have already
3283 * been removed from the primary pr_reg list), except the
3284 * new persistent reservation holder, the calling Initiator Port.
3285 */
3286 if (abort) {
3287 core_tmr_lun_reset(dev, NULL, &preempt_and_abort_list, cmd);
3288 core_scsi3_release_preempt_and_abort(&preempt_and_abort_list,
3289 pr_reg_n);
3290 }
3291
3292 if (pr_tmpl->pr_aptpl_active) {
Andy Grover59511462011-07-19 10:26:37 +00003293 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003294 &pr_reg_n->pr_aptpl_buf[0],
3295 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07003296 if (!ret)
3297 pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003298 "%s\n", (abort) ? "_AND_ABORT" : "");
3299 }
3300
3301 core_scsi3_put_pr_reg(pr_reg_n);
Andy Grover59511462011-07-19 10:26:37 +00003302 core_scsi3_pr_generation(cmd->se_dev);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003303 return 0;
3304}
3305
3306static int core_scsi3_emulate_pro_preempt(
3307 struct se_cmd *cmd,
3308 int type,
3309 int scope,
3310 u64 res_key,
3311 u64 sa_res_key,
3312 int abort)
3313{
3314 int ret = 0;
3315
3316 switch (type) {
3317 case PR_TYPE_WRITE_EXCLUSIVE:
3318 case PR_TYPE_EXCLUSIVE_ACCESS:
3319 case PR_TYPE_WRITE_EXCLUSIVE_REGONLY:
3320 case PR_TYPE_EXCLUSIVE_ACCESS_REGONLY:
3321 case PR_TYPE_WRITE_EXCLUSIVE_ALLREG:
3322 case PR_TYPE_EXCLUSIVE_ACCESS_ALLREG:
3323 ret = core_scsi3_pro_preempt(cmd, type, scope,
3324 res_key, sa_res_key, abort);
3325 break;
3326 default:
Andy Grover6708bb22011-06-08 10:36:43 -07003327 pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003328 " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003329 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
3330 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003331 }
3332
3333 return ret;
3334}
3335
3336
3337static int core_scsi3_emulate_pro_register_and_move(
3338 struct se_cmd *cmd,
3339 u64 res_key,
3340 u64 sa_res_key,
3341 int aptpl,
3342 int unreg)
3343{
Andy Grovere3d6f902011-07-19 08:55:10 +00003344 struct se_session *se_sess = cmd->se_sess;
Andy Grover59511462011-07-19 10:26:37 +00003345 struct se_device *dev = cmd->se_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003346 struct se_dev_entry *se_deve, *dest_se_deve = NULL;
Andy Grovere3d6f902011-07-19 08:55:10 +00003347 struct se_lun *se_lun = cmd->se_lun;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003348 struct se_node_acl *pr_res_nacl, *pr_reg_nacl, *dest_node_acl = NULL;
3349 struct se_port *se_port;
3350 struct se_portal_group *se_tpg, *dest_se_tpg = NULL;
3351 struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops;
3352 struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;
Andy Grovere3d6f902011-07-19 08:55:10 +00003353 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Andy Grover05d1c7c2011-07-20 19:13:28 +00003354 unsigned char *buf;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003355 unsigned char *initiator_str;
3356 char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN];
3357 u32 tid_len, tmp_tid_len;
3358 int new_reg = 0, type, scope, ret, matching_iname, prf_isid;
3359 unsigned short rtpi;
3360 unsigned char proto_ident;
3361
Andy Grover6708bb22011-06-08 10:36:43 -07003362 if (!se_sess || !se_lun) {
3363 pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003364 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3365 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003366 }
3367 memset(dest_iport, 0, 64);
3368 memset(i_buf, 0, PR_REG_ISID_ID_LEN);
3369 se_tpg = se_sess->se_tpg;
Andy Grovere3d6f902011-07-19 08:55:10 +00003370 tf_ops = se_tpg->se_tpg_tfo;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003371 se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
3372 /*
3373 * Follow logic from spc4r17 Section 5.7.8, Table 50 --
3374 * Register behaviors for a REGISTER AND MOVE service action
3375 *
3376 * Locate the existing *pr_reg via struct se_node_acl pointers
3377 */
Andy Grover59511462011-07-19 10:26:37 +00003378 pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003379 se_sess);
Andy Grover6708bb22011-06-08 10:36:43 -07003380 if (!pr_reg) {
3381 pr_err("SPC-3 PR: Unable to locate PR_REGISTERED"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003382 " *pr_reg for REGISTER_AND_MOVE\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003383 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3384 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003385 }
3386 /*
3387 * The provided reservation key much match the existing reservation key
3388 * provided during this initiator's I_T nexus registration.
3389 */
3390 if (res_key != pr_reg->pr_res_key) {
Andy Grover6708bb22011-06-08 10:36:43 -07003391 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003392 " res_key: 0x%016Lx does not match existing SA REGISTER"
3393 " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key);
3394 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003395 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
3396 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003397 }
3398 /*
3399 * The service active reservation key needs to be non zero
3400 */
Andy Grover6708bb22011-06-08 10:36:43 -07003401 if (!sa_res_key) {
3402 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003403 " sa_res_key\n");
3404 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003405 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3406 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003407 }
Andy Grover05d1c7c2011-07-20 19:13:28 +00003408
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003409 /*
3410 * Determine the Relative Target Port Identifier where the reservation
3411 * will be moved to for the TransportID containing SCSI initiator WWN
3412 * information.
3413 */
Andy Grover49493142012-01-16 16:57:08 -08003414 buf = transport_kmap_data_sg(cmd);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003415 rtpi = (buf[18] & 0xff) << 8;
3416 rtpi |= buf[19] & 0xff;
3417 tid_len = (buf[20] & 0xff) << 24;
3418 tid_len |= (buf[21] & 0xff) << 16;
3419 tid_len |= (buf[22] & 0xff) << 8;
3420 tid_len |= buf[23] & 0xff;
Andy Grover49493142012-01-16 16:57:08 -08003421 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00003422 buf = NULL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003423
3424 if ((tid_len + 24) != cmd->data_length) {
Andy Grover6708bb22011-06-08 10:36:43 -07003425 pr_err("SPC-3 PR: Illegal tid_len: %u + 24 byte header"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003426 " does not equal CDB data_length: %u\n", tid_len,
3427 cmd->data_length);
3428 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003429 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3430 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003431 }
3432
3433 spin_lock(&dev->se_port_lock);
3434 list_for_each_entry(se_port, &dev->dev_sep_list, sep_list) {
3435 if (se_port->sep_rtpi != rtpi)
3436 continue;
3437 dest_se_tpg = se_port->sep_tpg;
Andy Grover6708bb22011-06-08 10:36:43 -07003438 if (!dest_se_tpg)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003439 continue;
Andy Grovere3d6f902011-07-19 08:55:10 +00003440 dest_tf_ops = dest_se_tpg->se_tpg_tfo;
Andy Grover6708bb22011-06-08 10:36:43 -07003441 if (!dest_tf_ops)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003442 continue;
3443
3444 atomic_inc(&dest_se_tpg->tpg_pr_ref_count);
3445 smp_mb__after_atomic_inc();
3446 spin_unlock(&dev->se_port_lock);
3447
3448 ret = core_scsi3_tpg_depend_item(dest_se_tpg);
3449 if (ret != 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07003450 pr_err("core_scsi3_tpg_depend_item() failed"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003451 " for dest_se_tpg\n");
3452 atomic_dec(&dest_se_tpg->tpg_pr_ref_count);
3453 smp_mb__after_atomic_dec();
3454 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003455 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3456 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003457 }
3458
3459 spin_lock(&dev->se_port_lock);
3460 break;
3461 }
3462 spin_unlock(&dev->se_port_lock);
3463
Andy Grover6708bb22011-06-08 10:36:43 -07003464 if (!dest_se_tpg || !dest_tf_ops) {
3465 pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003466 " fabric ops from Relative Target Port Identifier:"
3467 " %hu\n", rtpi);
3468 core_scsi3_put_pr_reg(pr_reg);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003469 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3470 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003471 }
Andy Grover05d1c7c2011-07-20 19:13:28 +00003472
Andy Grover49493142012-01-16 16:57:08 -08003473 buf = transport_kmap_data_sg(cmd);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003474 proto_ident = (buf[24] & 0x0f);
3475#if 0
Andy Grover6708bb22011-06-08 10:36:43 -07003476 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Extracted Protocol Identifier:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003477 " 0x%02x\n", proto_ident);
3478#endif
3479 if (proto_ident != dest_tf_ops->get_fabric_proto_ident(dest_se_tpg)) {
Andy Grover6708bb22011-06-08 10:36:43 -07003480 pr_err("SPC-3 PR REGISTER_AND_MOVE: Received"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003481 " proto_ident: 0x%02x does not match ident: 0x%02x"
3482 " from fabric: %s\n", proto_ident,
3483 dest_tf_ops->get_fabric_proto_ident(dest_se_tpg),
3484 dest_tf_ops->get_fabric_name());
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003485 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3486 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003487 goto out;
3488 }
3489 if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) {
Andy Grover6708bb22011-06-08 10:36:43 -07003490 pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003491 " containg a valid tpg_parse_pr_out_transport_id"
3492 " function pointer\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003493 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3494 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003495 goto out;
3496 }
3497 initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg,
3498 (const char *)&buf[24], &tmp_tid_len, &iport_ptr);
Andy Grover6708bb22011-06-08 10:36:43 -07003499 if (!initiator_str) {
3500 pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003501 " initiator_str from Transport ID\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003502 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3503 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003504 goto out;
3505 }
3506
Andy Grover49493142012-01-16 16:57:08 -08003507 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00003508 buf = NULL;
3509
Andy Grover6708bb22011-06-08 10:36:43 -07003510 pr_debug("SPC-3 PR [%s] Extracted initiator %s identifier: %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003511 " %s\n", dest_tf_ops->get_fabric_name(), (iport_ptr != NULL) ?
3512 "port" : "device", initiator_str, (iport_ptr != NULL) ?
3513 iport_ptr : "");
3514 /*
3515 * If a PERSISTENT RESERVE OUT command with a REGISTER AND MOVE service
3516 * action specifies a TransportID that is the same as the initiator port
3517 * of the I_T nexus for the command received, then the command shall
3518 * be terminated with CHECK CONDITION status, with the sense key set to
3519 * ILLEGAL REQUEST, and the additional sense code set to INVALID FIELD
3520 * IN PARAMETER LIST.
3521 */
3522 pr_reg_nacl = pr_reg->pr_reg_nacl;
3523 matching_iname = (!strcmp(initiator_str,
3524 pr_reg_nacl->initiatorname)) ? 1 : 0;
Andy Grover6708bb22011-06-08 10:36:43 -07003525 if (!matching_iname)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003526 goto after_iport_check;
3527
Andy Grover6708bb22011-06-08 10:36:43 -07003528 if (!iport_ptr || !pr_reg->isid_present_at_reg) {
3529 pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003530 " matches: %s on received I_T Nexus\n", initiator_str,
3531 pr_reg_nacl->initiatorname);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003532 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3533 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003534 goto out;
3535 }
Andy Grover6708bb22011-06-08 10:36:43 -07003536 if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) {
3537 pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s %s"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003538 " matches: %s %s on received I_T Nexus\n",
3539 initiator_str, iport_ptr, pr_reg_nacl->initiatorname,
3540 pr_reg->pr_reg_isid);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003541 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3542 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003543 goto out;
3544 }
3545after_iport_check:
3546 /*
3547 * Locate the destination struct se_node_acl from the received Transport ID
3548 */
Roland Dreier28638882011-08-16 09:40:01 -07003549 spin_lock_irq(&dest_se_tpg->acl_node_lock);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003550 dest_node_acl = __core_tpg_get_initiator_node_acl(dest_se_tpg,
3551 initiator_str);
3552 if (dest_node_acl) {
3553 atomic_inc(&dest_node_acl->acl_pr_ref_count);
3554 smp_mb__after_atomic_inc();
3555 }
Roland Dreier28638882011-08-16 09:40:01 -07003556 spin_unlock_irq(&dest_se_tpg->acl_node_lock);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003557
Andy Grover6708bb22011-06-08 10:36:43 -07003558 if (!dest_node_acl) {
3559 pr_err("Unable to locate %s dest_node_acl for"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003560 " TransportID%s\n", dest_tf_ops->get_fabric_name(),
3561 initiator_str);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003562 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3563 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003564 goto out;
3565 }
3566 ret = core_scsi3_nodeacl_depend_item(dest_node_acl);
3567 if (ret != 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07003568 pr_err("core_scsi3_nodeacl_depend_item() for"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003569 " dest_node_acl\n");
3570 atomic_dec(&dest_node_acl->acl_pr_ref_count);
3571 smp_mb__after_atomic_dec();
3572 dest_node_acl = NULL;
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003573 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3574 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003575 goto out;
3576 }
3577#if 0
Andy Grover6708bb22011-06-08 10:36:43 -07003578 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Found %s dest_node_acl:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003579 " %s from TransportID\n", dest_tf_ops->get_fabric_name(),
3580 dest_node_acl->initiatorname);
3581#endif
3582 /*
3583 * Locate the struct se_dev_entry pointer for the matching RELATIVE TARGET
3584 * PORT IDENTIFIER.
3585 */
3586 dest_se_deve = core_get_se_deve_from_rtpi(dest_node_acl, rtpi);
Andy Grover6708bb22011-06-08 10:36:43 -07003587 if (!dest_se_deve) {
3588 pr_err("Unable to locate %s dest_se_deve from RTPI:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003589 " %hu\n", dest_tf_ops->get_fabric_name(), rtpi);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003590 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3591 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003592 goto out;
3593 }
3594
3595 ret = core_scsi3_lunacl_depend_item(dest_se_deve);
3596 if (ret < 0) {
Andy Grover6708bb22011-06-08 10:36:43 -07003597 pr_err("core_scsi3_lunacl_depend_item() failed\n");
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003598 atomic_dec(&dest_se_deve->pr_ref_count);
3599 smp_mb__after_atomic_dec();
3600 dest_se_deve = NULL;
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003601 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3602 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003603 goto out;
3604 }
3605#if 0
Andy Grover6708bb22011-06-08 10:36:43 -07003606 pr_debug("SPC-3 PR REGISTER_AND_MOVE: Located %s node %s LUN"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003607 " ACL for dest_se_deve->mapped_lun: %u\n",
3608 dest_tf_ops->get_fabric_name(), dest_node_acl->initiatorname,
3609 dest_se_deve->mapped_lun);
3610#endif
3611 /*
3612 * A persistent reservation needs to already existing in order to
3613 * successfully complete the REGISTER_AND_MOVE service action..
3614 */
3615 spin_lock(&dev->dev_reservation_lock);
3616 pr_res_holder = dev->dev_pr_res_holder;
Andy Grover6708bb22011-06-08 10:36:43 -07003617 if (!pr_res_holder) {
3618 pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003619 " currently held\n");
3620 spin_unlock(&dev->dev_reservation_lock);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003621 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
3622 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003623 goto out;
3624 }
3625 /*
3626 * The received on I_T Nexus must be the reservation holder.
3627 *
3628 * From spc4r17 section 5.7.8 Table 50 --
3629 * Register behaviors for a REGISTER AND MOVE service action
3630 */
3631 if (pr_res_holder != pr_reg) {
Andy Grover6708bb22011-06-08 10:36:43 -07003632 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003633 " Nexus is not reservation holder\n");
3634 spin_unlock(&dev->dev_reservation_lock);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003635 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
3636 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003637 goto out;
3638 }
3639 /*
3640 * From spc4r17 section 5.7.8: registering and moving reservation
3641 *
3642 * If a PERSISTENT RESERVE OUT command with a REGISTER AND MOVE service
3643 * action is received and the established persistent reservation is a
3644 * Write Exclusive - All Registrants type or Exclusive Access -
3645 * All Registrants type reservation, then the command shall be completed
3646 * with RESERVATION CONFLICT status.
3647 */
3648 if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
3649 (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) {
Andy Grover6708bb22011-06-08 10:36:43 -07003650 pr_warn("SPC-3 PR REGISTER_AND_MOVE: Unable to move"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003651 " reservation for type: %s\n",
3652 core_scsi3_pr_dump_type(pr_res_holder->pr_res_type));
3653 spin_unlock(&dev->dev_reservation_lock);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003654 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
3655 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003656 goto out;
3657 }
3658 pr_res_nacl = pr_res_holder->pr_reg_nacl;
3659 /*
3660 * b) Ignore the contents of the (received) SCOPE and TYPE fields;
3661 */
3662 type = pr_res_holder->pr_res_type;
3663 scope = pr_res_holder->pr_res_type;
3664 /*
3665 * c) Associate the reservation key specified in the SERVICE ACTION
3666 * RESERVATION KEY field with the I_T nexus specified as the
3667 * destination of the register and move, where:
3668 * A) The I_T nexus is specified by the TransportID and the
3669 * RELATIVE TARGET PORT IDENTIFIER field (see 6.14.4); and
3670 * B) Regardless of the TransportID format used, the association for
3671 * the initiator port is based on either the initiator port name
3672 * (see 3.1.71) on SCSI transport protocols where port names are
3673 * required or the initiator port identifier (see 3.1.70) on SCSI
3674 * transport protocols where port names are not required;
3675 * d) Register the reservation key specified in the SERVICE ACTION
3676 * RESERVATION KEY field;
3677 * e) Retain the reservation key specified in the SERVICE ACTION
3678 * RESERVATION KEY field and associated information;
3679 *
3680 * Also, It is not an error for a REGISTER AND MOVE service action to
3681 * register an I_T nexus that is already registered with the same
3682 * reservation key or a different reservation key.
3683 */
3684 dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
3685 iport_ptr);
Andy Grover6708bb22011-06-08 10:36:43 -07003686 if (!dest_pr_reg) {
Andy Grover59511462011-07-19 10:26:37 +00003687 ret = core_scsi3_alloc_registration(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003688 dest_node_acl, dest_se_deve, iport_ptr,
3689 sa_res_key, 0, aptpl, 2, 1);
3690 if (ret != 0) {
3691 spin_unlock(&dev->dev_reservation_lock);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003692 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3693 ret = -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003694 goto out;
3695 }
3696 dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
3697 iport_ptr);
3698 new_reg = 1;
3699 }
3700 /*
3701 * f) Release the persistent reservation for the persistent reservation
3702 * holder (i.e., the I_T nexus on which the
3703 */
3704 __core_scsi3_complete_pro_release(dev, pr_res_nacl,
3705 dev->dev_pr_res_holder, 0);
3706 /*
3707 * g) Move the persistent reservation to the specified I_T nexus using
3708 * the same scope and type as the persistent reservation released in
3709 * item f); and
3710 */
3711 dev->dev_pr_res_holder = dest_pr_reg;
3712 dest_pr_reg->pr_res_holder = 1;
3713 dest_pr_reg->pr_res_type = type;
3714 pr_reg->pr_res_scope = scope;
3715 prf_isid = core_pr_dump_initiator_port(pr_reg, &i_buf[0],
3716 PR_REG_ISID_ID_LEN);
3717 /*
3718 * Increment PRGeneration for existing registrations..
3719 */
Andy Grover6708bb22011-06-08 10:36:43 -07003720 if (!new_reg)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003721 dest_pr_reg->pr_res_generation = pr_tmpl->pr_generation++;
3722 spin_unlock(&dev->dev_reservation_lock);
3723
Andy Grover6708bb22011-06-08 10:36:43 -07003724 pr_debug("SPC-3 PR [%s] Service Action: REGISTER_AND_MOVE"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003725 " created new reservation holder TYPE: %s on object RTPI:"
3726 " %hu PRGeneration: 0x%08x\n", dest_tf_ops->get_fabric_name(),
3727 core_scsi3_pr_dump_type(type), rtpi,
3728 dest_pr_reg->pr_res_generation);
Andy Grover6708bb22011-06-08 10:36:43 -07003729 pr_debug("SPC-3 PR Successfully moved reservation from"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003730 " %s Fabric Node: %s%s -> %s Fabric Node: %s %s\n",
3731 tf_ops->get_fabric_name(), pr_reg_nacl->initiatorname,
3732 (prf_isid) ? &i_buf[0] : "", dest_tf_ops->get_fabric_name(),
3733 dest_node_acl->initiatorname, (iport_ptr != NULL) ?
3734 iport_ptr : "");
3735 /*
3736 * It is now safe to release configfs group dependencies for destination
3737 * of Transport ID Initiator Device/Port Identifier
3738 */
3739 core_scsi3_lunacl_undepend_item(dest_se_deve);
3740 core_scsi3_nodeacl_undepend_item(dest_node_acl);
3741 core_scsi3_tpg_undepend_item(dest_se_tpg);
3742 /*
3743 * h) If the UNREG bit is set to one, unregister (see 5.7.11.3) the I_T
3744 * nexus on which PERSISTENT RESERVE OUT command was received.
3745 */
3746 if (unreg) {
3747 spin_lock(&pr_tmpl->registration_lock);
3748 __core_scsi3_free_registration(dev, pr_reg, NULL, 1);
3749 spin_unlock(&pr_tmpl->registration_lock);
3750 } else
3751 core_scsi3_put_pr_reg(pr_reg);
3752
3753 /*
3754 * Clear the APTPL metadata if APTPL has been disabled, otherwise
3755 * write out the updated metadata to struct file for this SCSI device.
3756 */
Andy Grover6708bb22011-06-08 10:36:43 -07003757 if (!aptpl) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003758 pr_tmpl->pr_aptpl_active = 0;
Andy Grover59511462011-07-19 10:26:37 +00003759 core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0);
Andy Grover6708bb22011-06-08 10:36:43 -07003760 pr_debug("SPC-3 PR: Set APTPL Bit Deactivated for"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003761 " REGISTER_AND_MOVE\n");
3762 } else {
3763 pr_tmpl->pr_aptpl_active = 1;
Andy Grover59511462011-07-19 10:26:37 +00003764 ret = core_scsi3_update_and_write_aptpl(cmd->se_dev,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003765 &dest_pr_reg->pr_aptpl_buf[0],
3766 pr_tmpl->pr_aptpl_buf_len);
Andy Grover6708bb22011-06-08 10:36:43 -07003767 if (!ret)
3768 pr_debug("SPC-3 PR: Set APTPL Bit Activated for"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003769 " REGISTER_AND_MOVE\n");
3770 }
3771
Andy Grover49493142012-01-16 16:57:08 -08003772 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00003773
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003774 core_scsi3_put_pr_reg(dest_pr_reg);
3775 return 0;
3776out:
Andy Grover05d1c7c2011-07-20 19:13:28 +00003777 if (buf)
Andy Grover49493142012-01-16 16:57:08 -08003778 transport_kunmap_data_sg(cmd);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003779 if (dest_se_deve)
3780 core_scsi3_lunacl_undepend_item(dest_se_deve);
3781 if (dest_node_acl)
3782 core_scsi3_nodeacl_undepend_item(dest_node_acl);
3783 core_scsi3_tpg_undepend_item(dest_se_tpg);
3784 core_scsi3_put_pr_reg(pr_reg);
3785 return ret;
3786}
3787
3788static unsigned long long core_scsi3_extract_reservation_key(unsigned char *cdb)
3789{
3790 unsigned int __v1, __v2;
3791
3792 __v1 = (cdb[0] << 24) | (cdb[1] << 16) | (cdb[2] << 8) | cdb[3];
3793 __v2 = (cdb[4] << 24) | (cdb[5] << 16) | (cdb[6] << 8) | cdb[7];
3794
3795 return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32;
3796}
3797
3798/*
3799 * See spc4r17 section 6.14 Table 170
3800 */
Christoph Hellwige76a35d2011-11-03 17:50:42 -04003801int target_scsi3_emulate_pr_out(struct se_task *task)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003802{
Christoph Hellwige76a35d2011-11-03 17:50:42 -04003803 struct se_cmd *cmd = task->task_se_cmd;
Christoph Hellwig617c0e02011-11-03 17:50:41 -04003804 unsigned char *cdb = &cmd->t_task_cdb[0];
Andy Grover05d1c7c2011-07-20 19:13:28 +00003805 unsigned char *buf;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003806 u64 res_key, sa_res_key;
3807 int sa, scope, type, aptpl;
3808 int spec_i_pt = 0, all_tg_pt = 0, unreg = 0;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003809 int ret;
Christoph Hellwig617c0e02011-11-03 17:50:41 -04003810
3811 /*
3812 * Following spc2r20 5.5.1 Reservations overview:
3813 *
3814 * If a logical unit has been reserved by any RESERVE command and is
3815 * still reserved by any initiator, all PERSISTENT RESERVE IN and all
3816 * PERSISTENT RESERVE OUT commands shall conflict regardless of
3817 * initiator or service action and shall terminate with a RESERVATION
3818 * CONFLICT status.
3819 */
3820 if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
3821 pr_err("Received PERSISTENT_RESERVE CDB while legacy"
3822 " SPC-2 reservation is held, returning"
3823 " RESERVATION_CONFLICT\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003824 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
3825 ret = EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003826 goto out;
Christoph Hellwig617c0e02011-11-03 17:50:41 -04003827 }
3828
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003829 /*
3830 * FIXME: A NULL struct se_session pointer means an this is not coming from
3831 * a $FABRIC_MOD's nexus, but from internal passthrough ops.
3832 */
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003833 if (!cmd->se_sess) {
3834 cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
3835 return -EINVAL;
3836 }
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003837
3838 if (cmd->data_length < 24) {
Andy Grover6708bb22011-06-08 10:36:43 -07003839 pr_warn("SPC-PR: Received PR OUT parameter list"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003840 " length too small: %u\n", cmd->data_length);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003841 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3842 ret = -EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003843 goto out;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003844 }
3845 /*
3846 * From the PERSISTENT_RESERVE_OUT command descriptor block (CDB)
3847 */
3848 sa = (cdb[1] & 0x1f);
3849 scope = (cdb[2] & 0xf0);
3850 type = (cdb[2] & 0x0f);
Andy Grover05d1c7c2011-07-20 19:13:28 +00003851
Andy Grover49493142012-01-16 16:57:08 -08003852 buf = transport_kmap_data_sg(cmd);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003853 /*
3854 * From PERSISTENT_RESERVE_OUT parameter list (payload)
3855 */
3856 res_key = core_scsi3_extract_reservation_key(&buf[0]);
3857 sa_res_key = core_scsi3_extract_reservation_key(&buf[8]);
3858 /*
3859 * REGISTER_AND_MOVE uses a different SA parameter list containing
3860 * SCSI TransportIDs.
3861 */
3862 if (sa != PRO_REGISTER_AND_MOVE) {
3863 spec_i_pt = (buf[20] & 0x08);
3864 all_tg_pt = (buf[20] & 0x04);
3865 aptpl = (buf[20] & 0x01);
3866 } else {
3867 aptpl = (buf[17] & 0x01);
3868 unreg = (buf[17] & 0x02);
3869 }
Andy Grover49493142012-01-16 16:57:08 -08003870 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00003871 buf = NULL;
3872
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003873 /*
3874 * SPEC_I_PT=1 is only valid for Service action: REGISTER
3875 */
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003876 if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) {
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003877 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3878 ret = -EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003879 goto out;
3880 }
3881
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003882 /*
3883 * From spc4r17 section 6.14:
3884 *
3885 * If the SPEC_I_PT bit is set to zero, the service action is not
3886 * REGISTER AND MOVE, and the parameter list length is not 24, then
3887 * the command shall be terminated with CHECK CONDITION status, with
3888 * the sense key set to ILLEGAL REQUEST, and the additional sense
3889 * code set to PARAMETER LIST LENGTH ERROR.
3890 */
Andy Grover6708bb22011-06-08 10:36:43 -07003891 if (!spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER_AND_MOVE) &&
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003892 (cmd->data_length != 24)) {
Andy Grover6708bb22011-06-08 10:36:43 -07003893 pr_warn("SPC-PR: Received PR OUT illegal parameter"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003894 " list length: %u\n", cmd->data_length);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003895 cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
3896 ret = -EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003897 goto out;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003898 }
3899 /*
3900 * (core_scsi3_emulate_pro_* function parameters
3901 * are defined by spc4r17 Table 174:
3902 * PERSISTENT_RESERVE_OUT service actions and valid parameters.
3903 */
3904 switch (sa) {
3905 case PRO_REGISTER:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003906 ret = core_scsi3_emulate_pro_register(cmd,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003907 res_key, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 0);
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003908 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003909 case PRO_RESERVE:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003910 ret = core_scsi3_emulate_pro_reserve(cmd, type, scope, res_key);
3911 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003912 case PRO_RELEASE:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003913 ret = core_scsi3_emulate_pro_release(cmd, type, scope, res_key);
3914 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003915 case PRO_CLEAR:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003916 ret = core_scsi3_emulate_pro_clear(cmd, res_key);
3917 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003918 case PRO_PREEMPT:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003919 ret = core_scsi3_emulate_pro_preempt(cmd, type, scope,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003920 res_key, sa_res_key, 0);
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003921 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003922 case PRO_PREEMPT_AND_ABORT:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003923 ret = core_scsi3_emulate_pro_preempt(cmd, type, scope,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003924 res_key, sa_res_key, 1);
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003925 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003926 case PRO_REGISTER_AND_IGNORE_EXISTING_KEY:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003927 ret = core_scsi3_emulate_pro_register(cmd,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003928 0, sa_res_key, aptpl, all_tg_pt, spec_i_pt, 1);
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003929 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003930 case PRO_REGISTER_AND_MOVE:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003931 ret = core_scsi3_emulate_pro_register_and_move(cmd, res_key,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003932 sa_res_key, aptpl, unreg);
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003933 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003934 default:
Andy Grover6708bb22011-06-08 10:36:43 -07003935 pr_err("Unknown PERSISTENT_RESERVE_OUT service"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003936 " action: 0x%02x\n", cdb[1] & 0x1f);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003937 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
3938 ret = -EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003939 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003940 }
3941
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04003942out:
3943 if (!ret) {
3944 task->task_scsi_status = GOOD;
3945 transport_complete_task(task, 1);
3946 }
3947 return ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003948}
3949
3950/*
3951 * PERSISTENT_RESERVE_IN Service Action READ_KEYS
3952 *
3953 * See spc4r17 section 5.7.6.2 and section 6.13.2, Table 160
3954 */
3955static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
3956{
Andy Grover59511462011-07-19 10:26:37 +00003957 struct se_device *se_dev = cmd->se_dev;
Andy Grovere3d6f902011-07-19 08:55:10 +00003958 struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003959 struct t10_pr_registration *pr_reg;
Andy Grover05d1c7c2011-07-20 19:13:28 +00003960 unsigned char *buf;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003961 u32 add_len = 0, off = 8;
3962
3963 if (cmd->data_length < 8) {
Andy Grover6708bb22011-06-08 10:36:43 -07003964 pr_err("PRIN SA READ_KEYS SCSI Data Length: %u"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003965 " too small\n", cmd->data_length);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07003966 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
3967 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003968 }
3969
Andy Grover49493142012-01-16 16:57:08 -08003970 buf = transport_kmap_data_sg(cmd);
Andy Grovere3d6f902011-07-19 08:55:10 +00003971 buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
3972 buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
3973 buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
3974 buf[3] = (su_dev->t10_pr.pr_generation & 0xff);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003975
Andy Grovere3d6f902011-07-19 08:55:10 +00003976 spin_lock(&su_dev->t10_pr.registration_lock);
3977 list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003978 pr_reg_list) {
3979 /*
3980 * Check for overflow of 8byte PRI READ_KEYS payload and
3981 * next reservation key list descriptor.
3982 */
3983 if ((add_len + 8) > (cmd->data_length - 8))
3984 break;
3985
3986 buf[off++] = ((pr_reg->pr_res_key >> 56) & 0xff);
3987 buf[off++] = ((pr_reg->pr_res_key >> 48) & 0xff);
3988 buf[off++] = ((pr_reg->pr_res_key >> 40) & 0xff);
3989 buf[off++] = ((pr_reg->pr_res_key >> 32) & 0xff);
3990 buf[off++] = ((pr_reg->pr_res_key >> 24) & 0xff);
3991 buf[off++] = ((pr_reg->pr_res_key >> 16) & 0xff);
3992 buf[off++] = ((pr_reg->pr_res_key >> 8) & 0xff);
3993 buf[off++] = (pr_reg->pr_res_key & 0xff);
3994
3995 add_len += 8;
3996 }
Andy Grovere3d6f902011-07-19 08:55:10 +00003997 spin_unlock(&su_dev->t10_pr.registration_lock);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08003998
3999 buf[4] = ((add_len >> 24) & 0xff);
4000 buf[5] = ((add_len >> 16) & 0xff);
4001 buf[6] = ((add_len >> 8) & 0xff);
4002 buf[7] = (add_len & 0xff);
4003
Andy Grover49493142012-01-16 16:57:08 -08004004 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00004005
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004006 return 0;
4007}
4008
4009/*
4010 * PERSISTENT_RESERVE_IN Service Action READ_RESERVATION
4011 *
4012 * See spc4r17 section 5.7.6.3 and section 6.13.3.2 Table 161 and 162
4013 */
4014static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
4015{
Andy Grover59511462011-07-19 10:26:37 +00004016 struct se_device *se_dev = cmd->se_dev;
Andy Grovere3d6f902011-07-19 08:55:10 +00004017 struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004018 struct t10_pr_registration *pr_reg;
Andy Grover05d1c7c2011-07-20 19:13:28 +00004019 unsigned char *buf;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004020 u64 pr_res_key;
4021 u32 add_len = 16; /* Hardcoded to 16 when a reservation is held. */
4022
4023 if (cmd->data_length < 8) {
Andy Grover6708bb22011-06-08 10:36:43 -07004024 pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004025 " too small\n", cmd->data_length);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07004026 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
4027 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004028 }
4029
Andy Grover49493142012-01-16 16:57:08 -08004030 buf = transport_kmap_data_sg(cmd);
Andy Grovere3d6f902011-07-19 08:55:10 +00004031 buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
4032 buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
4033 buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
4034 buf[3] = (su_dev->t10_pr.pr_generation & 0xff);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004035
4036 spin_lock(&se_dev->dev_reservation_lock);
4037 pr_reg = se_dev->dev_pr_res_holder;
4038 if ((pr_reg)) {
4039 /*
4040 * Set the hardcoded Additional Length
4041 */
4042 buf[4] = ((add_len >> 24) & 0xff);
4043 buf[5] = ((add_len >> 16) & 0xff);
4044 buf[6] = ((add_len >> 8) & 0xff);
4045 buf[7] = (add_len & 0xff);
4046
Andy Grover05d1c7c2011-07-20 19:13:28 +00004047 if (cmd->data_length < 22)
4048 goto err;
4049
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004050 /*
4051 * Set the Reservation key.
4052 *
4053 * From spc4r17, section 5.7.10:
4054 * A persistent reservation holder has its reservation key
4055 * returned in the parameter data from a PERSISTENT
4056 * RESERVE IN command with READ RESERVATION service action as
4057 * follows:
4058 * a) For a persistent reservation of the type Write Exclusive
4059 * - All Registrants or Exclusive Access ­ All Regitrants,
4060 * the reservation key shall be set to zero; or
4061 * b) For all other persistent reservation types, the
4062 * reservation key shall be set to the registered
4063 * reservation key for the I_T nexus that holds the
4064 * persistent reservation.
4065 */
4066 if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) ||
4067 (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))
4068 pr_res_key = 0;
4069 else
4070 pr_res_key = pr_reg->pr_res_key;
4071
4072 buf[8] = ((pr_res_key >> 56) & 0xff);
4073 buf[9] = ((pr_res_key >> 48) & 0xff);
4074 buf[10] = ((pr_res_key >> 40) & 0xff);
4075 buf[11] = ((pr_res_key >> 32) & 0xff);
4076 buf[12] = ((pr_res_key >> 24) & 0xff);
4077 buf[13] = ((pr_res_key >> 16) & 0xff);
4078 buf[14] = ((pr_res_key >> 8) & 0xff);
4079 buf[15] = (pr_res_key & 0xff);
4080 /*
4081 * Set the SCOPE and TYPE
4082 */
4083 buf[21] = (pr_reg->pr_res_scope & 0xf0) |
4084 (pr_reg->pr_res_type & 0x0f);
4085 }
Andy Grover05d1c7c2011-07-20 19:13:28 +00004086
4087err:
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004088 spin_unlock(&se_dev->dev_reservation_lock);
Andy Grover49493142012-01-16 16:57:08 -08004089 transport_kunmap_data_sg(cmd);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004090
4091 return 0;
4092}
4093
4094/*
4095 * PERSISTENT_RESERVE_IN Service Action REPORT_CAPABILITIES
4096 *
4097 * See spc4r17 section 6.13.4 Table 165
4098 */
4099static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
4100{
Andy Grover59511462011-07-19 10:26:37 +00004101 struct se_device *dev = cmd->se_dev;
Andy Grovere3d6f902011-07-19 08:55:10 +00004102 struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
Andy Grover05d1c7c2011-07-20 19:13:28 +00004103 unsigned char *buf;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004104 u16 add_len = 8; /* Hardcoded to 8. */
4105
4106 if (cmd->data_length < 6) {
Andy Grover6708bb22011-06-08 10:36:43 -07004107 pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004108 " %u too small\n", cmd->data_length);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07004109 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
4110 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004111 }
4112
Andy Grover49493142012-01-16 16:57:08 -08004113 buf = transport_kmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00004114
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004115 buf[0] = ((add_len << 8) & 0xff);
4116 buf[1] = (add_len & 0xff);
4117 buf[2] |= 0x10; /* CRH: Compatible Reservation Hanlding bit. */
4118 buf[2] |= 0x08; /* SIP_C: Specify Initiator Ports Capable bit */
4119 buf[2] |= 0x04; /* ATP_C: All Target Ports Capable bit */
4120 buf[2] |= 0x01; /* PTPL_C: Persistence across Target Power Loss bit */
4121 /*
4122 * We are filling in the PERSISTENT RESERVATION TYPE MASK below, so
4123 * set the TMV: Task Mask Valid bit.
4124 */
4125 buf[3] |= 0x80;
4126 /*
4127 * Change ALLOW COMMANDs to 0x20 or 0x40 later from Table 166
4128 */
4129 buf[3] |= 0x10; /* ALLOW COMMANDs field 001b */
4130 /*
4131 * PTPL_A: Persistence across Target Power Loss Active bit
4132 */
4133 if (pr_tmpl->pr_aptpl_active)
4134 buf[3] |= 0x01;
4135 /*
4136 * Setup the PERSISTENT RESERVATION TYPE MASK from Table 167
4137 */
4138 buf[4] |= 0x80; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
4139 buf[4] |= 0x40; /* PR_TYPE_EXCLUSIVE_ACCESS_REGONLY */
4140 buf[4] |= 0x20; /* PR_TYPE_WRITE_EXCLUSIVE_REGONLY */
4141 buf[4] |= 0x08; /* PR_TYPE_EXCLUSIVE_ACCESS */
4142 buf[4] |= 0x02; /* PR_TYPE_WRITE_EXCLUSIVE */
4143 buf[5] |= 0x01; /* PR_TYPE_EXCLUSIVE_ACCESS_ALLREG */
4144
Andy Grover49493142012-01-16 16:57:08 -08004145 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00004146
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004147 return 0;
4148}
4149
4150/*
4151 * PERSISTENT_RESERVE_IN Service Action READ_FULL_STATUS
4152 *
4153 * See spc4r17 section 6.13.5 Table 168 and 169
4154 */
4155static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
4156{
Andy Grover59511462011-07-19 10:26:37 +00004157 struct se_device *se_dev = cmd->se_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004158 struct se_node_acl *se_nacl;
Andy Grovere3d6f902011-07-19 08:55:10 +00004159 struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004160 struct se_portal_group *se_tpg;
4161 struct t10_pr_registration *pr_reg, *pr_reg_tmp;
Andy Grovere3d6f902011-07-19 08:55:10 +00004162 struct t10_reservation *pr_tmpl = &se_dev->se_sub_dev->t10_pr;
Andy Grover05d1c7c2011-07-20 19:13:28 +00004163 unsigned char *buf;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004164 u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
4165 u32 off = 8; /* off into first Full Status descriptor */
4166 int format_code = 0;
4167
4168 if (cmd->data_length < 8) {
Andy Grover6708bb22011-06-08 10:36:43 -07004169 pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004170 " too small\n", cmd->data_length);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07004171 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
4172 return -EINVAL;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004173 }
4174
Andy Grover49493142012-01-16 16:57:08 -08004175 buf = transport_kmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00004176
Andy Grovere3d6f902011-07-19 08:55:10 +00004177 buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
4178 buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
4179 buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
4180 buf[3] = (su_dev->t10_pr.pr_generation & 0xff);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004181
4182 spin_lock(&pr_tmpl->registration_lock);
4183 list_for_each_entry_safe(pr_reg, pr_reg_tmp,
4184 &pr_tmpl->registration_list, pr_reg_list) {
4185
4186 se_nacl = pr_reg->pr_reg_nacl;
4187 se_tpg = pr_reg->pr_reg_nacl->se_tpg;
4188 add_desc_len = 0;
4189
4190 atomic_inc(&pr_reg->pr_res_holders);
4191 smp_mb__after_atomic_inc();
4192 spin_unlock(&pr_tmpl->registration_lock);
4193 /*
4194 * Determine expected length of $FABRIC_MOD specific
4195 * TransportID full status descriptor..
4196 */
Andy Grovere3d6f902011-07-19 08:55:10 +00004197 exp_desc_len = se_tpg->se_tpg_tfo->tpg_get_pr_transport_id_len(
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004198 se_tpg, se_nacl, pr_reg, &format_code);
4199
4200 if ((exp_desc_len + add_len) > cmd->data_length) {
Andy Grover6708bb22011-06-08 10:36:43 -07004201 pr_warn("SPC-3 PRIN READ_FULL_STATUS ran"
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004202 " out of buffer: %d\n", cmd->data_length);
4203 spin_lock(&pr_tmpl->registration_lock);
4204 atomic_dec(&pr_reg->pr_res_holders);
4205 smp_mb__after_atomic_dec();
4206 break;
4207 }
4208 /*
4209 * Set RESERVATION KEY
4210 */
4211 buf[off++] = ((pr_reg->pr_res_key >> 56) & 0xff);
4212 buf[off++] = ((pr_reg->pr_res_key >> 48) & 0xff);
4213 buf[off++] = ((pr_reg->pr_res_key >> 40) & 0xff);
4214 buf[off++] = ((pr_reg->pr_res_key >> 32) & 0xff);
4215 buf[off++] = ((pr_reg->pr_res_key >> 24) & 0xff);
4216 buf[off++] = ((pr_reg->pr_res_key >> 16) & 0xff);
4217 buf[off++] = ((pr_reg->pr_res_key >> 8) & 0xff);
4218 buf[off++] = (pr_reg->pr_res_key & 0xff);
4219 off += 4; /* Skip Over Reserved area */
4220
4221 /*
4222 * Set ALL_TG_PT bit if PROUT SA REGISTER had this set.
4223 */
4224 if (pr_reg->pr_reg_all_tg_pt)
4225 buf[off] = 0x02;
4226 /*
4227 * The struct se_lun pointer will be present for the
4228 * reservation holder for PR_HOLDER bit.
4229 *
4230 * Also, if this registration is the reservation
4231 * holder, fill in SCOPE and TYPE in the next byte.
4232 */
4233 if (pr_reg->pr_res_holder) {
4234 buf[off++] |= 0x01;
4235 buf[off++] = (pr_reg->pr_res_scope & 0xf0) |
4236 (pr_reg->pr_res_type & 0x0f);
4237 } else
4238 off += 2;
4239
4240 off += 4; /* Skip over reserved area */
4241 /*
4242 * From spc4r17 6.3.15:
4243 *
4244 * If the ALL_TG_PT bit set to zero, the RELATIVE TARGET PORT
4245 * IDENTIFIER field contains the relative port identifier (see
4246 * 3.1.120) of the target port that is part of the I_T nexus
4247 * described by this full status descriptor. If the ALL_TG_PT
4248 * bit is set to one, the contents of the RELATIVE TARGET PORT
4249 * IDENTIFIER field are not defined by this standard.
4250 */
Andy Grover6708bb22011-06-08 10:36:43 -07004251 if (!pr_reg->pr_reg_all_tg_pt) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004252 struct se_port *port = pr_reg->pr_reg_tg_pt_lun->lun_sep;
4253
4254 buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
4255 buf[off++] = (port->sep_rtpi & 0xff);
4256 } else
4257 off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFER */
4258
4259 /*
4260 * Now, have the $FABRIC_MOD fill in the protocol identifier
4261 */
Andy Grovere3d6f902011-07-19 08:55:10 +00004262 desc_len = se_tpg->se_tpg_tfo->tpg_get_pr_transport_id(se_tpg,
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004263 se_nacl, pr_reg, &format_code, &buf[off+4]);
4264
4265 spin_lock(&pr_tmpl->registration_lock);
4266 atomic_dec(&pr_reg->pr_res_holders);
4267 smp_mb__after_atomic_dec();
4268 /*
4269 * Set the ADDITIONAL DESCRIPTOR LENGTH
4270 */
4271 buf[off++] = ((desc_len >> 24) & 0xff);
4272 buf[off++] = ((desc_len >> 16) & 0xff);
4273 buf[off++] = ((desc_len >> 8) & 0xff);
4274 buf[off++] = (desc_len & 0xff);
4275 /*
4276 * Size of full desctipor header minus TransportID
4277 * containing $FABRIC_MOD specific) initiator device/port
4278 * WWN information.
4279 *
4280 * See spc4r17 Section 6.13.5 Table 169
4281 */
4282 add_desc_len = (24 + desc_len);
4283
4284 off += desc_len;
4285 add_len += add_desc_len;
4286 }
4287 spin_unlock(&pr_tmpl->registration_lock);
4288 /*
4289 * Set ADDITIONAL_LENGTH
4290 */
4291 buf[4] = ((add_len >> 24) & 0xff);
4292 buf[5] = ((add_len >> 16) & 0xff);
4293 buf[6] = ((add_len >> 8) & 0xff);
4294 buf[7] = (add_len & 0xff);
4295
Andy Grover49493142012-01-16 16:57:08 -08004296 transport_kunmap_data_sg(cmd);
Andy Grover05d1c7c2011-07-20 19:13:28 +00004297
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004298 return 0;
4299}
4300
Christoph Hellwige76a35d2011-11-03 17:50:42 -04004301int target_scsi3_emulate_pr_in(struct se_task *task)
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004302{
Christoph Hellwige76a35d2011-11-03 17:50:42 -04004303 struct se_cmd *cmd = task->task_se_cmd;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04004304 int ret;
Christoph Hellwige76a35d2011-11-03 17:50:42 -04004305
Christoph Hellwig617c0e02011-11-03 17:50:41 -04004306 /*
4307 * Following spc2r20 5.5.1 Reservations overview:
4308 *
4309 * If a logical unit has been reserved by any RESERVE command and is
4310 * still reserved by any initiator, all PERSISTENT RESERVE IN and all
4311 * PERSISTENT RESERVE OUT commands shall conflict regardless of
4312 * initiator or service action and shall terminate with a RESERVATION
4313 * CONFLICT status.
4314 */
4315 if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
4316 pr_err("Received PERSISTENT_RESERVE CDB while legacy"
4317 " SPC-2 reservation is held, returning"
4318 " RESERVATION_CONFLICT\n");
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07004319 cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
4320 return -EINVAL;
Christoph Hellwig617c0e02011-11-03 17:50:41 -04004321 }
4322
4323 switch (cmd->t_task_cdb[1] & 0x1f) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004324 case PRI_READ_KEYS:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04004325 ret = core_scsi3_pri_read_keys(cmd);
4326 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004327 case PRI_READ_RESERVATION:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04004328 ret = core_scsi3_pri_read_reservation(cmd);
4329 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004330 case PRI_REPORT_CAPABILITIES:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04004331 ret = core_scsi3_pri_report_capabilities(cmd);
4332 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004333 case PRI_READ_FULL_STATUS:
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04004334 ret = core_scsi3_pri_read_full_status(cmd);
4335 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004336 default:
Andy Grover6708bb22011-06-08 10:36:43 -07004337 pr_err("Unknown PERSISTENT_RESERVE_IN service"
Christoph Hellwig617c0e02011-11-03 17:50:41 -04004338 " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f);
Nicholas Bellinger03e98c92011-11-04 02:36:16 -07004339 cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
4340 ret = -EINVAL;
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04004341 break;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004342 }
Christoph Hellwigd29a5b62011-11-03 17:50:44 -04004343
4344 if (!ret) {
4345 task->task_scsi_status = GOOD;
4346 transport_complete_task(task, 1);
4347 }
4348 return ret;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004349}
4350
4351static int core_pt_reservation_check(struct se_cmd *cmd, u32 *pr_res_type)
4352{
4353 return 0;
4354}
4355
4356static int core_pt_seq_non_holder(
4357 struct se_cmd *cmd,
4358 unsigned char *cdb,
4359 u32 pr_reg_type)
4360{
4361 return 0;
4362}
4363
4364int core_setup_reservations(struct se_device *dev, int force_pt)
4365{
4366 struct se_subsystem_dev *su_dev = dev->se_sub_dev;
Andy Grovere3d6f902011-07-19 08:55:10 +00004367 struct t10_reservation *rest = &su_dev->t10_pr;
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004368 /*
4369 * If this device is from Target_Core_Mod/pSCSI, use the reservations
4370 * of the Underlying SCSI hardware. In Linux/SCSI terms, this can
4371 * cause a problem because libata and some SATA RAID HBAs appear
4372 * under Linux/SCSI, but to emulate reservations themselves.
4373 */
Andy Grovere3d6f902011-07-19 08:55:10 +00004374 if (((dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) &&
4375 !(dev->se_sub_dev->se_dev_attrib.emulate_reservations)) || force_pt) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004376 rest->res_type = SPC_PASSTHROUGH;
4377 rest->pr_ops.t10_reservation_check = &core_pt_reservation_check;
4378 rest->pr_ops.t10_seq_non_holder = &core_pt_seq_non_holder;
Andy Grover6708bb22011-06-08 10:36:43 -07004379 pr_debug("%s: Using SPC_PASSTHROUGH, no reservation"
Andy Grovere3d6f902011-07-19 08:55:10 +00004380 " emulation\n", dev->transport->name);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004381 return 0;
4382 }
4383 /*
4384 * If SPC-3 or above is reported by real or emulated struct se_device,
4385 * use emulated Persistent Reservations.
4386 */
Andy Grovere3d6f902011-07-19 08:55:10 +00004387 if (dev->transport->get_device_rev(dev) >= SCSI_3) {
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004388 rest->res_type = SPC3_PERSISTENT_RESERVATIONS;
4389 rest->pr_ops.t10_reservation_check = &core_scsi3_pr_reservation_check;
4390 rest->pr_ops.t10_seq_non_holder = &core_scsi3_pr_seq_non_holder;
Andy Grover6708bb22011-06-08 10:36:43 -07004391 pr_debug("%s: Using SPC3_PERSISTENT_RESERVATIONS"
Andy Grovere3d6f902011-07-19 08:55:10 +00004392 " emulation\n", dev->transport->name);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004393 } else {
4394 rest->res_type = SPC2_RESERVATIONS;
4395 rest->pr_ops.t10_reservation_check = &core_scsi2_reservation_check;
4396 rest->pr_ops.t10_seq_non_holder =
4397 &core_scsi2_reservation_seq_non_holder;
Andy Grover6708bb22011-06-08 10:36:43 -07004398 pr_debug("%s: Using SPC2_RESERVATIONS emulation\n",
Andy Grovere3d6f902011-07-19 08:55:10 +00004399 dev->transport->name);
Nicholas Bellingerc66ac9d2010-12-17 11:11:26 -08004400 }
4401
4402 return 0;
4403}