xref: /spdk/lib/scsi/scsi_pr.c (revision cde2142cd008f2fa6b0edb2a9194c36c7df6da52)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2019 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "scsi_internal.h"
7 
8 #include "spdk/endian.h"
9 
10 /* Get registrant by I_T nexus */
11 static struct spdk_scsi_pr_registrant *
scsi_pr_get_registrant(struct spdk_scsi_lun * lun,struct spdk_scsi_port * initiator_port,struct spdk_scsi_port * target_port)12 scsi_pr_get_registrant(struct spdk_scsi_lun *lun,
13 		       struct spdk_scsi_port *initiator_port,
14 		       struct spdk_scsi_port *target_port)
15 {
16 	struct spdk_scsi_pr_registrant *reg, *tmp;
17 
18 	TAILQ_FOREACH_SAFE(reg, &lun->reg_head, link, tmp) {
19 		if (initiator_port == reg->initiator_port &&
20 		    target_port == reg->target_port) {
21 			return reg;
22 		}
23 	}
24 
25 	return NULL;
26 }
27 
28 static bool
scsi2_it_nexus_is_holder(struct spdk_scsi_lun * lun,struct spdk_scsi_port * initiator_port,struct spdk_scsi_port * target_port)29 scsi2_it_nexus_is_holder(struct spdk_scsi_lun *lun,
30 			 struct spdk_scsi_port *initiator_port,
31 			 struct spdk_scsi_port *target_port)
32 {
33 	struct spdk_scsi_pr_registrant *reg = lun->reservation.holder;
34 
35 	assert(reg != NULL);
36 
37 	if ((reg->initiator_port == initiator_port) &&
38 	    (reg->target_port == target_port)) {
39 		return true;
40 	}
41 
42 	return false;
43 }
44 
45 /* Reservation type is all registrants or not */
46 static inline bool
scsi_pr_is_all_registrants_type(struct spdk_scsi_lun * lun)47 scsi_pr_is_all_registrants_type(struct spdk_scsi_lun *lun)
48 {
49 	return (lun->reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS ||
50 		lun->reservation.rtype == SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS);
51 }
52 
53 /* Registrant is reservation holder or not */
54 static inline bool
scsi_pr_registrant_is_holder(struct spdk_scsi_lun * lun,struct spdk_scsi_pr_registrant * reg)55 scsi_pr_registrant_is_holder(struct spdk_scsi_lun *lun,
56 			     struct spdk_scsi_pr_registrant *reg)
57 {
58 	if (reg != NULL && scsi_pr_is_all_registrants_type(lun)) {
59 		return true;
60 	}
61 
62 	return (lun->reservation.holder == reg);
63 }
64 
65 /* LUN holds a reservation or not */
66 static inline bool
scsi_pr_has_reservation(struct spdk_scsi_lun * lun)67 scsi_pr_has_reservation(struct spdk_scsi_lun *lun)
68 {
69 	return !(lun->reservation.holder == NULL);
70 }
71 
72 static int
scsi_pr_register_registrant(struct spdk_scsi_lun * lun,struct spdk_scsi_port * initiator_port,struct spdk_scsi_port * target_port,uint64_t sa_rkey)73 scsi_pr_register_registrant(struct spdk_scsi_lun *lun,
74 			    struct spdk_scsi_port *initiator_port,
75 			    struct spdk_scsi_port *target_port,
76 			    uint64_t sa_rkey)
77 {
78 	struct spdk_scsi_pr_registrant *reg;
79 
80 	/* Register sa_rkey with the I_T nexus */
81 	reg = calloc(1, sizeof(*reg));
82 	if (!reg) {
83 		return -ENOMEM;
84 	}
85 
86 	SPDK_DEBUGLOG(scsi, "REGISTER: new registrant registered "
87 		      "with key 0x%"PRIx64"\n", sa_rkey);
88 
89 	/* New I_T nexus */
90 	reg->initiator_port = initiator_port;
91 	if (initiator_port) {
92 		snprintf(reg->initiator_port_name, sizeof(reg->initiator_port_name), "%s",
93 			 initiator_port->name);
94 		reg->transport_id_len = initiator_port->transport_id_len;
95 		memcpy(reg->transport_id, initiator_port->transport_id, reg->transport_id_len);
96 	}
97 	reg->target_port = target_port;
98 	if (target_port) {
99 		snprintf(reg->target_port_name, sizeof(reg->target_port_name), "%s",
100 			 target_port->name);
101 		reg->relative_target_port_id = target_port->index;
102 	}
103 	reg->rkey = sa_rkey;
104 	TAILQ_INSERT_TAIL(&lun->reg_head, reg, link);
105 	lun->pr_generation++;
106 
107 	return 0;
108 }
109 
110 static void
scsi_pr_release_reservation(struct spdk_scsi_lun * lun,struct spdk_scsi_pr_registrant * reg)111 scsi_pr_release_reservation(struct spdk_scsi_lun *lun, struct spdk_scsi_pr_registrant *reg)
112 {
113 	bool all_regs = false;
114 	struct spdk_scsi_pr_registrant *curr_reg, *tmp;
115 
116 	SPDK_DEBUGLOG(scsi, "REGISTER: release reservation "
117 		      "with type %u\n", lun->reservation.rtype);
118 
119 	/* TODO: Unit Attention */
120 	all_regs = scsi_pr_is_all_registrants_type(lun);
121 	if (all_regs) {
122 		TAILQ_FOREACH_SAFE(curr_reg, &lun->reg_head, link, tmp) {
123 			if (curr_reg != reg) {
124 				lun->reservation.holder = curr_reg;
125 				lun->reservation.crkey = curr_reg->rkey;
126 				return;
127 			}
128 		}
129 	}
130 
131 	memset(&lun->reservation, 0, sizeof(struct spdk_scsi_pr_reservation));
132 }
133 
134 static void
scsi_pr_reserve_reservation(struct spdk_scsi_lun * lun,enum spdk_scsi_pr_type_code type,uint64_t rkey,struct spdk_scsi_pr_registrant * holder)135 scsi_pr_reserve_reservation(struct spdk_scsi_lun *lun,
136 			    enum spdk_scsi_pr_type_code type,
137 			    uint64_t rkey,
138 			    struct spdk_scsi_pr_registrant *holder)
139 {
140 	lun->reservation.rtype = type;
141 	lun->reservation.crkey = rkey;
142 	lun->reservation.holder = holder;
143 }
144 
145 static void
scsi_pr_unregister_registrant(struct spdk_scsi_lun * lun,struct spdk_scsi_pr_registrant * reg)146 scsi_pr_unregister_registrant(struct spdk_scsi_lun *lun,
147 			      struct spdk_scsi_pr_registrant *reg)
148 {
149 	SPDK_DEBUGLOG(scsi, "REGISTER: unregister registrant\n");
150 
151 	TAILQ_REMOVE(&lun->reg_head, reg, link);
152 	if (scsi_pr_registrant_is_holder(lun, reg)) {
153 		scsi_pr_release_reservation(lun, reg);
154 	}
155 
156 	free(reg);
157 	lun->pr_generation++;
158 }
159 
160 static void
scsi_pr_replace_registrant_key(struct spdk_scsi_lun * lun,struct spdk_scsi_pr_registrant * reg,uint64_t sa_rkey)161 scsi_pr_replace_registrant_key(struct spdk_scsi_lun *lun,
162 			       struct spdk_scsi_pr_registrant *reg,
163 			       uint64_t sa_rkey)
164 {
165 	SPDK_DEBUGLOG(scsi, "REGISTER: replace with new "
166 		      "reservation key 0x%"PRIx64"\n", sa_rkey);
167 	reg->rkey = sa_rkey;
168 	lun->pr_generation++;
169 }
170 
171 static int
scsi_pr_out_reserve(struct spdk_scsi_task * task,enum spdk_scsi_pr_type_code rtype,uint64_t rkey,uint8_t spec_i_pt,uint8_t all_tg_pt,uint8_t aptpl)172 scsi_pr_out_reserve(struct spdk_scsi_task *task,
173 		    enum spdk_scsi_pr_type_code rtype, uint64_t rkey,
174 		    uint8_t spec_i_pt, uint8_t all_tg_pt, uint8_t aptpl)
175 {
176 	struct spdk_scsi_lun *lun = task->lun;
177 	struct spdk_scsi_pr_registrant *reg;
178 
179 	SPDK_DEBUGLOG(scsi, "PR OUT RESERVE: rkey 0x%"PRIx64", requested "
180 		      "reservation type %u, type %u\n", rkey, rtype, lun->reservation.rtype);
181 
182 	/* TODO: don't support now */
183 	if (spec_i_pt || all_tg_pt || aptpl) {
184 		SPDK_ERRLOG("Unsupported spec_i_pt/all_tg_pt fields "
185 			    "or invalid aptpl field\n");
186 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
187 					  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
188 					  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
189 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
190 		return -EINVAL;
191 	}
192 
193 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
194 	/* No registration for the I_T nexus */
195 	if (!reg) {
196 		SPDK_ERRLOG("No registration\n");
197 		goto conflict;
198 	}
199 
200 	/* invalid reservation key */
201 	if (reg->rkey != rkey) {
202 		SPDK_ERRLOG("Reservation key 0x%"PRIx64" don't match 0x%"PRIx64"\n",
203 			    rkey, reg->rkey);
204 		goto conflict;
205 	}
206 
207 	/* reservation holder already exists */
208 	if (scsi_pr_has_reservation(lun)) {
209 		if (rtype != lun->reservation.rtype) {
210 			SPDK_ERRLOG("Reservation type doesn't match\n");
211 			goto conflict;
212 		}
213 
214 		if (!scsi_pr_registrant_is_holder(lun, reg)) {
215 			SPDK_ERRLOG("Only 1 holder is allowed for type %u\n", rtype);
216 			goto conflict;
217 		}
218 	} else {
219 		/* current I_T nexus is the first reservation holder */
220 		scsi_pr_reserve_reservation(lun, rtype, rkey, reg);
221 	}
222 
223 	return 0;
224 
225 conflict:
226 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_RESERVATION_CONFLICT,
227 				  SPDK_SCSI_SENSE_NO_SENSE,
228 				  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
229 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
230 	return -EINVAL;
231 }
232 
233 static int
scsi_pr_out_register(struct spdk_scsi_task * task,enum spdk_scsi_pr_out_service_action_code action,uint64_t rkey,uint64_t sa_rkey,uint8_t spec_i_pt,uint8_t all_tg_pt,uint8_t aptpl)234 scsi_pr_out_register(struct spdk_scsi_task *task,
235 		     enum spdk_scsi_pr_out_service_action_code action,
236 		     uint64_t rkey, uint64_t sa_rkey,
237 		     uint8_t spec_i_pt, uint8_t all_tg_pt, uint8_t aptpl)
238 {
239 	struct spdk_scsi_lun *lun = task->lun;
240 	struct spdk_scsi_pr_registrant *reg;
241 	int sc, sk, asc;
242 
243 	SPDK_DEBUGLOG(scsi, "PR OUT REGISTER: rkey 0x%"PRIx64", "
244 		      "sa_key 0x%"PRIx64", reservation type %u\n", rkey, sa_rkey, lun->reservation.rtype);
245 
246 	/* TODO: don't support now */
247 	if (spec_i_pt || all_tg_pt || aptpl) {
248 		SPDK_ERRLOG("Unsupported spec_i_pt/all_tg_pt/aptpl field\n");
249 		sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
250 		sk = SPDK_SCSI_SENSE_ILLEGAL_REQUEST;
251 		asc = SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB;
252 		goto error_exit;
253 	}
254 
255 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
256 	/* an unregistered I_T nexus session */
257 	if (!reg) {
258 		if (rkey && (action == SPDK_SCSI_PR_OUT_REGISTER)) {
259 			SPDK_ERRLOG("Reservation key field is not empty\n");
260 			sc = SPDK_SCSI_STATUS_RESERVATION_CONFLICT;
261 			sk = SPDK_SCSI_SENSE_NO_SENSE;
262 			asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
263 			goto error_exit;
264 		}
265 
266 		if (!sa_rkey) {
267 			/* Do nothing except return GOOD status */
268 			SPDK_DEBUGLOG(scsi, "REGISTER: service action "
269 				      "reservation key is zero, do noting\n");
270 			return 0;
271 		}
272 		/* Add a new registrant for the I_T nexus */
273 		return scsi_pr_register_registrant(lun, task->initiator_port,
274 						   task->target_port, sa_rkey);
275 	} else {
276 		/* a registered I_T nexus */
277 		if (rkey != reg->rkey && action == SPDK_SCSI_PR_OUT_REGISTER) {
278 			SPDK_ERRLOG("Reservation key 0x%"PRIx64" don't match "
279 				    "registrant's key 0x%"PRIx64"\n", rkey, reg->rkey);
280 			sc = SPDK_SCSI_STATUS_RESERVATION_CONFLICT;
281 			sk = SPDK_SCSI_SENSE_NO_SENSE;
282 			asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
283 			goto error_exit;
284 		}
285 
286 		if (!sa_rkey) {
287 			/* unregister */
288 			scsi_pr_unregister_registrant(lun, reg);
289 		} else {
290 			/* replace */
291 			scsi_pr_replace_registrant_key(lun, reg, sa_rkey);
292 		}
293 	}
294 
295 	return 0;
296 
297 error_exit:
298 	spdk_scsi_task_set_status(task, sc, sk, asc, SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE);
299 	return -EINVAL;
300 }
301 
302 static int
scsi_pr_out_release(struct spdk_scsi_task * task,enum spdk_scsi_pr_type_code rtype,uint64_t rkey)303 scsi_pr_out_release(struct spdk_scsi_task *task,
304 		    enum spdk_scsi_pr_type_code rtype, uint64_t rkey)
305 {
306 	struct spdk_scsi_lun *lun = task->lun;
307 	struct spdk_scsi_pr_registrant *reg;
308 	int sk, asc;
309 
310 	SPDK_DEBUGLOG(scsi, "PR OUT RELEASE: rkey 0x%"PRIx64", "
311 		      "reservation type %u\n", rkey, rtype);
312 
313 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
314 	if (!reg) {
315 		SPDK_ERRLOG("No registration\n");
316 		sk = SPDK_SCSI_SENSE_NOT_READY;
317 		asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
318 		goto check_condition;
319 	}
320 
321 	/* no reservation holder */
322 	if (!scsi_pr_has_reservation(lun)) {
323 		SPDK_DEBUGLOG(scsi, "RELEASE: no reservation holder\n");
324 		return 0;
325 	}
326 
327 	if (lun->reservation.rtype != rtype || rkey != lun->reservation.crkey) {
328 		sk = SPDK_SCSI_SENSE_ILLEGAL_REQUEST;
329 		asc = SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB;
330 		goto check_condition;
331 	}
332 
333 	/* I_T nexus is not a persistent reservation holder */
334 	if (!scsi_pr_registrant_is_holder(lun, reg)) {
335 		SPDK_DEBUGLOG(scsi, "RELEASE: current I_T nexus is not holder\n");
336 		return 0;
337 	}
338 
339 	scsi_pr_release_reservation(lun, reg);
340 
341 	return 0;
342 
343 check_condition:
344 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION, sk, asc,
345 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
346 	return -EINVAL;
347 }
348 
349 static int
scsi_pr_out_clear(struct spdk_scsi_task * task,uint64_t rkey)350 scsi_pr_out_clear(struct spdk_scsi_task *task, uint64_t rkey)
351 {
352 	struct spdk_scsi_lun *lun = task->lun;
353 	struct spdk_scsi_pr_registrant *reg, *tmp;
354 	int sc, sk, asc;
355 
356 	SPDK_DEBUGLOG(scsi, "PR OUT CLEAR: rkey 0x%"PRIx64"\n", rkey);
357 
358 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
359 	if (!reg) {
360 		SPDK_ERRLOG("No registration\n");
361 		sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
362 		sk = SPDK_SCSI_SENSE_NOT_READY;
363 		asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
364 		goto error_exit;
365 	}
366 
367 	if (rkey != reg->rkey) {
368 		SPDK_ERRLOG("Reservation key 0x%"PRIx64" doesn't match "
369 			    "registrant's key 0x%"PRIx64"\n", rkey, reg->rkey);
370 		sc = SPDK_SCSI_STATUS_RESERVATION_CONFLICT;
371 		sk = SPDK_SCSI_SENSE_NO_SENSE;
372 		asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
373 		goto error_exit;
374 	}
375 
376 	TAILQ_FOREACH_SAFE(reg, &lun->reg_head, link, tmp) {
377 		scsi_pr_unregister_registrant(lun, reg);
378 	}
379 
380 	return 0;
381 
382 error_exit:
383 	spdk_scsi_task_set_status(task, sc, sk, asc, SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
384 	return -EINVAL;
385 }
386 
387 static void
scsi_pr_remove_all_regs_by_key(struct spdk_scsi_lun * lun,uint64_t sa_rkey)388 scsi_pr_remove_all_regs_by_key(struct spdk_scsi_lun *lun, uint64_t sa_rkey)
389 {
390 	struct spdk_scsi_pr_registrant *reg, *tmp;
391 
392 	TAILQ_FOREACH_SAFE(reg, &lun->reg_head, link, tmp) {
393 		if (reg->rkey == sa_rkey) {
394 			scsi_pr_unregister_registrant(lun, reg);
395 		}
396 	}
397 }
398 
399 static void
scsi_pr_remove_all_other_regs(struct spdk_scsi_lun * lun,struct spdk_scsi_pr_registrant * reg)400 scsi_pr_remove_all_other_regs(struct spdk_scsi_lun *lun, struct spdk_scsi_pr_registrant *reg)
401 {
402 	struct spdk_scsi_pr_registrant *reg_tmp, *reg_tmp2;
403 
404 	TAILQ_FOREACH_SAFE(reg_tmp, &lun->reg_head, link, reg_tmp2) {
405 		if (reg_tmp != reg) {
406 			scsi_pr_unregister_registrant(lun, reg_tmp);
407 		}
408 	}
409 }
410 
411 static int
scsi_pr_out_preempt(struct spdk_scsi_task * task,enum spdk_scsi_pr_out_service_action_code action,enum spdk_scsi_pr_type_code rtype,uint64_t rkey,uint64_t sa_rkey)412 scsi_pr_out_preempt(struct spdk_scsi_task *task,
413 		    enum spdk_scsi_pr_out_service_action_code action,
414 		    enum spdk_scsi_pr_type_code rtype,
415 		    uint64_t rkey, uint64_t sa_rkey)
416 {
417 	struct spdk_scsi_lun *lun = task->lun;
418 	struct spdk_scsi_pr_registrant *reg;
419 	bool all_regs = false;
420 
421 	SPDK_DEBUGLOG(scsi, "PR OUT PREEMPT: rkey 0x%"PRIx64", sa_rkey 0x%"PRIx64" "
422 		      "action %u, type %u, reservation type %u\n",
423 		      rkey, sa_rkey, action, rtype, lun->reservation.rtype);
424 
425 	/* I_T nexus is not registered */
426 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
427 	if (!reg) {
428 		SPDK_ERRLOG("No registration\n");
429 		goto conflict;
430 	}
431 	if (rkey != reg->rkey) {
432 		SPDK_ERRLOG("Reservation key 0x%"PRIx64" doesn't match "
433 			    "registrant's key 0x%"PRIx64"\n", rkey, reg->rkey);
434 		goto conflict;
435 	}
436 
437 	/* no persistent reservation */
438 	if (!scsi_pr_has_reservation(lun)) {
439 		scsi_pr_remove_all_regs_by_key(lun, sa_rkey);
440 		SPDK_DEBUGLOG(scsi, "PREEMPT: no persistent reservation\n");
441 		goto exit;
442 	}
443 
444 	all_regs = scsi_pr_is_all_registrants_type(lun);
445 
446 	if (all_regs) {
447 		if (sa_rkey != 0) {
448 			scsi_pr_remove_all_regs_by_key(lun, sa_rkey);
449 			SPDK_DEBUGLOG(scsi, "PREEMPT: All registrants type with sa_rkey\n");
450 		} else {
451 			/* remove all other registrants and release persistent reservation if any */
452 			scsi_pr_remove_all_other_regs(lun, reg);
453 			/* create persistent reservation using new type and scope */
454 			scsi_pr_reserve_reservation(lun, rtype, 0, reg);
455 			SPDK_DEBUGLOG(scsi, "PREEMPT: All registrants type with sa_rkey zeroed\n");
456 		}
457 		goto exit;
458 	}
459 
460 	assert(lun->reservation.crkey != 0);
461 
462 	if (sa_rkey != lun->reservation.crkey) {
463 		if (!sa_rkey) {
464 			SPDK_ERRLOG("Zeroed sa_rkey\n");
465 			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
466 						  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
467 						  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
468 						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
469 			return -EINVAL;
470 		}
471 		scsi_pr_remove_all_regs_by_key(lun, sa_rkey);
472 		goto exit;
473 	}
474 
475 	if (scsi_pr_registrant_is_holder(lun, reg)) {
476 		scsi_pr_reserve_reservation(lun, rtype, rkey, reg);
477 		SPDK_DEBUGLOG(scsi, "PREEMPT: preempt itself with type %u\n", rtype);
478 		goto exit;
479 	}
480 
481 	/* unregister registrants if any */
482 	scsi_pr_remove_all_regs_by_key(lun, sa_rkey);
483 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
484 	if (!reg) {
485 		SPDK_ERRLOG("Current I_T nexus registrant was removed\n");
486 		goto conflict;
487 	}
488 
489 	/* preempt the holder */
490 	scsi_pr_reserve_reservation(lun, rtype, rkey, reg);
491 
492 exit:
493 	lun->pr_generation++;
494 	return 0;
495 
496 conflict:
497 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_RESERVATION_CONFLICT,
498 				  SPDK_SCSI_SENSE_NO_SENSE,
499 				  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
500 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
501 	return -EINVAL;
502 }
503 
504 int
scsi_pr_out(struct spdk_scsi_task * task,uint8_t * cdb,uint8_t * data,uint16_t data_len)505 scsi_pr_out(struct spdk_scsi_task *task, uint8_t *cdb,
506 	    uint8_t *data, uint16_t data_len)
507 {
508 	int rc = -1;
509 	uint64_t rkey, sa_rkey;
510 	uint8_t spec_i_pt, all_tg_pt, aptpl;
511 	enum spdk_scsi_pr_out_service_action_code action;
512 	enum spdk_scsi_pr_scope_code scope;
513 	enum spdk_scsi_pr_type_code rtype;
514 	struct spdk_scsi_pr_out_param_list *param = (struct spdk_scsi_pr_out_param_list *)data;
515 
516 	action = cdb[1] & 0x0f;
517 	scope = (cdb[2] >> 4) & 0x0f;
518 	rtype = cdb[2] & 0x0f;
519 
520 	rkey = from_be64(&param->rkey);
521 	sa_rkey = from_be64(&param->sa_rkey);
522 	aptpl = param->aptpl;
523 	spec_i_pt = param->spec_i_pt;
524 	all_tg_pt = param->all_tg_pt;
525 
526 	switch (action) {
527 	case SPDK_SCSI_PR_OUT_REGISTER:
528 	case SPDK_SCSI_PR_OUT_REG_AND_IGNORE_KEY:
529 		rc = scsi_pr_out_register(task, action, rkey, sa_rkey,
530 					  spec_i_pt, all_tg_pt, aptpl);
531 		break;
532 	case SPDK_SCSI_PR_OUT_RESERVE:
533 		if (scope != SPDK_SCSI_PR_LU_SCOPE) {
534 			goto invalid;
535 		}
536 		rc = scsi_pr_out_reserve(task, rtype, rkey,
537 					 spec_i_pt, all_tg_pt, aptpl);
538 		break;
539 	case SPDK_SCSI_PR_OUT_RELEASE:
540 		if (scope != SPDK_SCSI_PR_LU_SCOPE) {
541 			goto invalid;
542 		}
543 		rc = scsi_pr_out_release(task, rtype, rkey);
544 		break;
545 	case SPDK_SCSI_PR_OUT_CLEAR:
546 		rc = scsi_pr_out_clear(task, rkey);
547 		break;
548 	case SPDK_SCSI_PR_OUT_PREEMPT:
549 		if (scope != SPDK_SCSI_PR_LU_SCOPE) {
550 			goto invalid;
551 		}
552 		rc = scsi_pr_out_preempt(task, action, rtype, rkey, sa_rkey);
553 		break;
554 	default:
555 		SPDK_ERRLOG("Invalid service action code %u\n", action);
556 		goto invalid;
557 	}
558 
559 	return rc;
560 
561 invalid:
562 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
563 				  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
564 				  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
565 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
566 	return -EINVAL;
567 }
568 
569 static int
scsi_pr_in_read_keys(struct spdk_scsi_task * task,uint8_t * data,uint16_t data_len)570 scsi_pr_in_read_keys(struct spdk_scsi_task *task, uint8_t *data,
571 		     uint16_t data_len)
572 {
573 	struct spdk_scsi_lun *lun = task->lun;
574 	struct spdk_scsi_pr_in_read_keys_data *keys;
575 	struct spdk_scsi_pr_registrant *reg, *tmp;
576 	uint16_t count = 0;
577 
578 	SPDK_DEBUGLOG(scsi, "PR IN READ KEYS\n");
579 	keys = (struct spdk_scsi_pr_in_read_keys_data *)data;
580 
581 	to_be32(&keys->header.pr_generation, lun->pr_generation);
582 	TAILQ_FOREACH_SAFE(reg, &lun->reg_head, link, tmp) {
583 		if (((count + 1) * 8 + sizeof(keys->header)) > data_len) {
584 			break;
585 		}
586 		to_be64(&keys->rkeys[count], reg->rkey);
587 		count++;
588 	}
589 	to_be32(&keys->header.additional_len, count * 8);
590 
591 	return (sizeof(keys->header) + count * 8);
592 }
593 
594 static int
scsi_pr_in_read_reservations(struct spdk_scsi_task * task,uint8_t * data,uint16_t data_len)595 scsi_pr_in_read_reservations(struct spdk_scsi_task *task,
596 			     uint8_t *data, uint16_t data_len)
597 {
598 	struct spdk_scsi_lun *lun = task->lun;
599 	struct spdk_scsi_pr_in_read_reservations_data *param;
600 	bool all_regs = false;
601 
602 	SPDK_DEBUGLOG(scsi, "PR IN READ RESERVATIONS\n");
603 	param = (struct spdk_scsi_pr_in_read_reservations_data *)(data);
604 
605 	to_be32(&param->header.pr_generation, lun->pr_generation);
606 	if (scsi_pr_has_reservation(lun)) {
607 		all_regs = scsi_pr_is_all_registrants_type(lun);
608 		if (all_regs) {
609 			to_be64(&param->rkey, 0);
610 		} else {
611 			to_be64(&param->rkey, lun->reservation.crkey);
612 		}
613 		to_be32(&param->header.additional_len, 16);
614 		param->scope = SPDK_SCSI_PR_LU_SCOPE;
615 		param->type = lun->reservation.rtype;
616 		SPDK_DEBUGLOG(scsi, "READ RESERVATIONS with valid reservation\n");
617 		return sizeof(*param);
618 	}
619 
620 	/* no reservation */
621 	to_be32(&param->header.additional_len, 0);
622 	SPDK_DEBUGLOG(scsi, "READ RESERVATIONS no reservation\n");
623 	return sizeof(param->header);
624 }
625 
626 static int
scsi_pr_in_report_capabilities(struct spdk_scsi_task * task,uint8_t * data,uint16_t data_len)627 scsi_pr_in_report_capabilities(struct spdk_scsi_task *task,
628 			       uint8_t *data, uint16_t data_len)
629 {
630 	struct spdk_scsi_pr_in_report_capabilities_data *param;
631 
632 	SPDK_DEBUGLOG(scsi, "PR IN REPORT CAPABILITIES\n");
633 	param = (struct spdk_scsi_pr_in_report_capabilities_data *)data;
634 
635 	memset(param, 0, sizeof(*param));
636 	to_be16(&param->length, sizeof(*param));
637 	/* Compatible reservation handling to support RESERVE/RELEASE defined in SPC-2 */
638 	param->crh = 1;
639 	param->tmv = 1;
640 	param->wr_ex = 1;
641 	param->ex_ac = 1;
642 	param->wr_ex_ro = 1;
643 	param->ex_ac_ro = 1;
644 	param->wr_ex_ar = 1;
645 	param->ex_ac_ar = 1;
646 
647 	return sizeof(*param);
648 }
649 
650 static int
scsi_pr_in_read_full_status(struct spdk_scsi_task * task,uint8_t * data,uint16_t data_len)651 scsi_pr_in_read_full_status(struct spdk_scsi_task *task,
652 			    uint8_t *data, uint16_t data_len)
653 {
654 	struct spdk_scsi_lun *lun = task->lun;
655 	struct spdk_scsi_pr_in_full_status_data *param;
656 	struct spdk_scsi_pr_in_full_status_desc *desc;
657 	struct spdk_scsi_pr_registrant *reg, *tmp;
658 	bool all_regs = false;
659 	uint32_t add_len = 0;
660 
661 	SPDK_DEBUGLOG(scsi, "PR IN READ FULL STATUS\n");
662 
663 	all_regs = scsi_pr_is_all_registrants_type(lun);
664 	param = (struct spdk_scsi_pr_in_full_status_data *)data;
665 	to_be32(&param->header.pr_generation, lun->pr_generation);
666 
667 	TAILQ_FOREACH_SAFE(reg, &lun->reg_head, link, tmp) {
668 		desc = (struct spdk_scsi_pr_in_full_status_desc *)
669 		       ((uint8_t *)param->desc_list + add_len);
670 		if (add_len + sizeof(*desc) + sizeof(param->header) > data_len) {
671 			break;
672 		}
673 		add_len += sizeof(*desc);
674 		desc->rkey = reg->rkey;
675 		if (all_regs || lun->reservation.holder == reg) {
676 			desc->r_holder = true;
677 			desc->type = lun->reservation.rtype;
678 		} else {
679 			desc->r_holder = false;
680 			desc->type = 0;
681 		}
682 		desc->all_tg_pt = 0;
683 		desc->scope = SPDK_SCSI_PR_LU_SCOPE;
684 		desc->relative_target_port_id = reg->relative_target_port_id;
685 		if (add_len + reg->transport_id_len + sizeof(param->header) > data_len) {
686 			break;
687 		}
688 		add_len += reg->transport_id_len;
689 		memcpy(&desc->transport_id, reg->transport_id, reg->transport_id_len);
690 		to_be32(&desc->desc_len, reg->transport_id_len);
691 	}
692 	to_be32(&param->header.additional_len, add_len);
693 
694 	return (sizeof(param->header) + add_len);
695 }
696 
697 int
scsi_pr_in(struct spdk_scsi_task * task,uint8_t * cdb,uint8_t * data,uint16_t data_len)698 scsi_pr_in(struct spdk_scsi_task *task, uint8_t *cdb,
699 	   uint8_t *data, uint16_t data_len)
700 {
701 	enum spdk_scsi_pr_in_action_code action;
702 	int rc = 0;
703 
704 	action = cdb[1] & 0x1f;
705 	if (data_len < sizeof(struct spdk_scsi_pr_in_read_header)) {
706 		goto invalid;
707 	}
708 
709 	switch (action) {
710 	case SPDK_SCSI_PR_IN_READ_KEYS:
711 		rc = scsi_pr_in_read_keys(task, data, data_len);
712 		break;
713 	case SPDK_SCSI_PR_IN_READ_RESERVATION:
714 		if (data_len < sizeof(struct spdk_scsi_pr_in_read_reservations_data)) {
715 			goto invalid;
716 		}
717 		rc = scsi_pr_in_read_reservations(task, data, data_len);
718 		break;
719 	case SPDK_SCSI_PR_IN_REPORT_CAPABILITIES:
720 		rc = scsi_pr_in_report_capabilities(task, data, data_len);
721 		break;
722 	case SPDK_SCSI_PR_IN_READ_FULL_STATUS:
723 		rc = scsi_pr_in_read_full_status(task, data, data_len);
724 		break;
725 	default:
726 		goto invalid;
727 	}
728 
729 	return rc;
730 
731 invalid:
732 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
733 				  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
734 				  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
735 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
736 	return -EINVAL;
737 }
738 
739 int
scsi_pr_check(struct spdk_scsi_task * task)740 scsi_pr_check(struct spdk_scsi_task *task)
741 {
742 	struct spdk_scsi_lun *lun = task->lun;
743 	uint8_t *cdb = task->cdb;
744 	enum spdk_scsi_pr_type_code rtype;
745 	enum spdk_scsi_pr_out_service_action_code action;
746 	struct spdk_scsi_pr_registrant *reg;
747 	bool dma_to_device = false;
748 
749 	/* no reservation holders */
750 	if (!scsi_pr_has_reservation(lun)) {
751 		return 0;
752 	}
753 
754 	rtype = lun->reservation.rtype;
755 	assert(rtype != 0);
756 
757 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
758 	/* current I_T nexus hold the reservation */
759 	if (scsi_pr_registrant_is_holder(lun, reg)) {
760 		return 0;
761 	}
762 
763 	/* reservation is held by other I_T nexus */
764 	switch (cdb[0]) {
765 	case SPDK_SPC_INQUIRY:
766 	case SPDK_SPC_REPORT_LUNS:
767 	case SPDK_SPC_REQUEST_SENSE:
768 	case SPDK_SPC_LOG_SENSE:
769 	case SPDK_SPC_TEST_UNIT_READY:
770 	case SPDK_SBC_START_STOP_UNIT:
771 	case SPDK_SBC_READ_CAPACITY_10:
772 	case SPDK_SPC_PERSISTENT_RESERVE_IN:
773 	case SPDK_SPC_SERVICE_ACTION_IN_16:
774 	/* CRH enabled, processed by scsi2_reserve() */
775 	case SPDK_SPC2_RESERVE_6:
776 	case SPDK_SPC2_RESERVE_10:
777 	/* CRH enabled, processed by scsi2_release() */
778 	case SPDK_SPC2_RELEASE_6:
779 	case SPDK_SPC2_RELEASE_10:
780 		return 0;
781 	case SPDK_SPC_MODE_SELECT_6:
782 	case SPDK_SPC_MODE_SELECT_10:
783 	case SPDK_SPC_MODE_SENSE_6:
784 	case SPDK_SPC_MODE_SENSE_10:
785 	case SPDK_SPC_LOG_SELECT:
786 		/* I_T nexus is registrant but not holder */
787 		if (!reg) {
788 			SPDK_DEBUGLOG(scsi, "CHECK: current I_T nexus "
789 				      "is not registered, cdb 0x%x\n", cdb[0]);
790 			goto conflict;
791 		}
792 		return 0;
793 	case SPDK_SPC_PERSISTENT_RESERVE_OUT:
794 		action = cdb[1] & 0x1f;
795 		SPDK_DEBUGLOG(scsi, "CHECK: PR OUT action %u\n", action);
796 		switch (action) {
797 		case SPDK_SCSI_PR_OUT_RELEASE:
798 		case SPDK_SCSI_PR_OUT_CLEAR:
799 		case SPDK_SCSI_PR_OUT_PREEMPT:
800 		case SPDK_SCSI_PR_OUT_PREEMPT_AND_ABORT:
801 			if (!reg) {
802 				SPDK_ERRLOG("CHECK: PR OUT action %u\n", action);
803 				goto conflict;
804 			}
805 			return 0;
806 		case SPDK_SCSI_PR_OUT_REGISTER:
807 		case SPDK_SCSI_PR_OUT_REG_AND_IGNORE_KEY:
808 			return 0;
809 		case SPDK_SCSI_PR_OUT_REG_AND_MOVE:
810 			SPDK_ERRLOG("CHECK: PR OUT action %u\n", action);
811 			goto conflict;
812 		default:
813 			SPDK_ERRLOG("CHECK: PR OUT invalid action %u\n", action);
814 			goto conflict;
815 		}
816 
817 	/* For most SBC R/W commands */
818 	default:
819 		break;
820 	}
821 
822 	switch (cdb[0]) {
823 	case SPDK_SBC_READ_6:
824 	case SPDK_SBC_READ_10:
825 	case SPDK_SBC_READ_12:
826 	case SPDK_SBC_READ_16:
827 		break;
828 	case SPDK_SBC_WRITE_6:
829 	case SPDK_SBC_WRITE_10:
830 	case SPDK_SBC_WRITE_12:
831 	case SPDK_SBC_WRITE_16:
832 	case SPDK_SBC_UNMAP:
833 	case SPDK_SBC_SYNCHRONIZE_CACHE_10:
834 	case SPDK_SBC_SYNCHRONIZE_CACHE_16:
835 		dma_to_device = true;
836 		break;
837 	default:
838 		SPDK_ERRLOG("CHECK: unsupported SCSI command cdb 0x%x\n", cdb[0]);
839 		goto conflict;
840 	}
841 
842 	switch (rtype) {
843 	case SPDK_SCSI_PR_WRITE_EXCLUSIVE:
844 		if (dma_to_device) {
845 			SPDK_ERRLOG("CHECK: Write Exclusive reservation type "
846 				    "rejects command 0x%x\n", cdb[0]);
847 			goto conflict;
848 		}
849 		break;
850 	case SPDK_SCSI_PR_EXCLUSIVE_ACCESS:
851 		SPDK_ERRLOG("CHECK: Exclusive Access reservation type "
852 			    "rejects command 0x%x\n", cdb[0]);
853 		goto conflict;
854 	case SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY:
855 	case SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS:
856 		if (!reg && dma_to_device) {
857 			SPDK_ERRLOG("CHECK: Registrants only reservation "
858 				    "type  reject command 0x%x\n", cdb[0]);
859 			goto conflict;
860 		}
861 		break;
862 	case SPDK_SCSI_PR_EXCLUSIVE_ACCESS_REGS_ONLY:
863 	case SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS:
864 		if (!reg) {
865 			SPDK_ERRLOG("CHECK: All Registrants reservation "
866 				    "type  reject command 0x%x\n", cdb[0]);
867 			goto conflict;
868 		}
869 		break;
870 	default:
871 		break;
872 	}
873 
874 	return 0;
875 
876 conflict:
877 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_RESERVATION_CONFLICT,
878 				  SPDK_SCSI_SENSE_NO_SENSE,
879 				  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
880 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
881 	return -1;
882 }
883 
884 static int
scsi2_check_reservation_conflict(struct spdk_scsi_task * task)885 scsi2_check_reservation_conflict(struct spdk_scsi_task *task)
886 {
887 	struct spdk_scsi_lun *lun = task->lun;
888 	struct spdk_scsi_pr_registrant *reg;
889 	bool conflict = false;
890 
891 	reg = scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
892 	if (reg) {
893 		/*
894 		 * From spc4r31 5.9.3 Exceptions to SPC-2 RESERVE and RELEASE
895 		 * behavior
896 		 *
897 		 * A RESERVE(6) or RESERVE(10) command shall complete with GOOD
898 		 * status, but no reservation shall be established and the
899 		 * persistent reservation shall not be changed, if the command
900 		 * is received from a) and b) below.
901 		 *
902 		 * A RELEASE(6) or RELEASE(10) command shall complete with GOOD
903 		 * status, but the persistent reservation shall not be released,
904 		 * if the command is received from a) and b)
905 		 *
906 		 * a) An I_T nexus that is a persistent reservation holder; or
907 		 * b) An I_T nexus that is registered if a registrants only or
908 		 *    all registrants type persistent reservation is present.
909 		 *
910 		 * In all other cases, a RESERVE(6) command, RESERVE(10) command,
911 		 * RELEASE(6) command, or RELEASE(10) command shall be processed
912 		 * as defined in SPC-2.
913 		 */
914 		if (scsi_pr_registrant_is_holder(lun, reg)) {
915 			return 1;
916 		}
917 
918 		if (lun->reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY ||
919 		    lun->reservation.rtype == SPDK_SCSI_PR_EXCLUSIVE_ACCESS_REGS_ONLY) {
920 			return 1;
921 		}
922 
923 		conflict = true;
924 	} else {
925 		/*
926 		 * From spc2r20 5.5.1 Reservations overview:
927 		 *
928 		 * If a logical unit has executed a PERSISTENT RESERVE OUT
929 		 * command with the REGISTER or the REGISTER AND IGNORE
930 		 * EXISTING KEY service action and is still registered by any
931 		 * initiator, all RESERVE commands and all RELEASE commands
932 		 * regardless of initiator shall conflict and shall terminate
933 		 * with a RESERVATION CONFLICT status.
934 		 */
935 		conflict = TAILQ_EMPTY(&lun->reg_head) ? false : true;
936 	}
937 
938 	if (conflict) {
939 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_RESERVATION_CONFLICT,
940 					  SPDK_SCSI_SENSE_NO_SENSE,
941 					  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
942 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
943 		return -1;
944 	}
945 
946 	return 0;
947 }
948 
949 int
scsi2_reserve(struct spdk_scsi_task * task,uint8_t * cdb)950 scsi2_reserve(struct spdk_scsi_task *task, uint8_t *cdb)
951 {
952 	struct spdk_scsi_lun *lun = task->lun;
953 	struct spdk_scsi_pr_registrant *reg = &lun->scsi2_holder;
954 	int ret;
955 
956 	/* Obsolete Bits and LongID set, returning ILLEGAL_REQUEST */
957 	if (cdb[1] & 0x3) {
958 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
959 					  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
960 					  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
961 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
962 		return -1;
963 	}
964 
965 	ret = scsi2_check_reservation_conflict(task);
966 	/* PERSISTENT RESERVE is enabled */
967 	if (ret == 1) {
968 		return 0;
969 	} else if (ret < 0) {
970 		return ret;
971 	}
972 
973 	/* SPC2 RESERVE */
974 	reg->initiator_port = task->initiator_port;
975 	if (task->initiator_port) {
976 		snprintf(reg->initiator_port_name, sizeof(reg->initiator_port_name), "%s",
977 			 task->initiator_port->name);
978 		reg->transport_id_len = task->initiator_port->transport_id_len;
979 		memcpy(reg->transport_id, task->initiator_port->transport_id,
980 		       reg->transport_id_len);
981 	}
982 	reg->target_port = task->target_port;
983 	if (task->target_port) {
984 		snprintf(reg->target_port_name, sizeof(reg->target_port_name), "%s",
985 			 task->target_port->name);
986 	}
987 
988 	lun->reservation.flags = SCSI_SPC2_RESERVE;
989 	lun->reservation.holder = &lun->scsi2_holder;
990 
991 	return 0;
992 }
993 
994 int
scsi2_release(struct spdk_scsi_task * task)995 scsi2_release(struct spdk_scsi_task *task)
996 {
997 	struct spdk_scsi_lun *lun = task->lun;
998 	int ret;
999 
1000 	ret = scsi2_check_reservation_conflict(task);
1001 	/* PERSISTENT RESERVE is enabled */
1002 	if (ret == 1) {
1003 		return 0;
1004 	} else if (ret < 0) {
1005 		return ret;
1006 	}
1007 
1008 	if (!(lun->reservation.flags & SCSI_SPC2_RESERVE)) {
1009 		spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
1010 					  SPDK_SCSI_SENSE_ILLEGAL_REQUEST,
1011 					  SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB,
1012 					  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1013 		return -EINVAL;
1014 	}
1015 
1016 	memset(&lun->reservation, 0, sizeof(struct spdk_scsi_pr_reservation));
1017 	memset(&lun->scsi2_holder, 0, sizeof(struct spdk_scsi_pr_registrant));
1018 
1019 	return 0;
1020 }
1021 
1022 int
scsi2_reserve_check(struct spdk_scsi_task * task)1023 scsi2_reserve_check(struct spdk_scsi_task *task)
1024 {
1025 	struct spdk_scsi_lun *lun = task->lun;
1026 	uint8_t *cdb = task->cdb;
1027 
1028 	switch (cdb[0]) {
1029 	case SPDK_SPC_INQUIRY:
1030 	case SPDK_SPC2_RELEASE_6:
1031 	case SPDK_SPC2_RELEASE_10:
1032 		return 0;
1033 
1034 	default:
1035 		break;
1036 	}
1037 
1038 	/* no reservation holders */
1039 	if (!scsi_pr_has_reservation(lun)) {
1040 		return 0;
1041 	}
1042 
1043 	if (scsi2_it_nexus_is_holder(lun, task->initiator_port, task->target_port)) {
1044 		return 0;
1045 	}
1046 
1047 	spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_RESERVATION_CONFLICT,
1048 				  SPDK_SCSI_SENSE_NO_SENSE,
1049 				  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
1050 				  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
1051 	return -1;
1052 }
1053