scsi: add persistent reservation out with release service action support
An application client releases the persistent reservation by issuing a PERSISTENT RESERVE OUT command with RELEASE service action through an I_T nexus that is a persistent reservation holder. The RELEASE service action will release the persistent reservation and do noting to existing registrants. Unit Attention isn't supported by SPDK so here we will not establish any unit attention condition. Change-Id: If0df3b3fc4e89ffa78d827e2b31cf5c61aa149db Signed-off-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/436090 Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
601fbbf969
commit
e8e791f7b5
@ -293,6 +293,54 @@ error_exit:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_scsi_pr_out_release(struct spdk_scsi_task *task,
|
||||
enum spdk_scsi_pr_type_code rtype, uint64_t rkey)
|
||||
{
|
||||
struct spdk_scsi_lun *lun = task->lun;
|
||||
struct spdk_scsi_pr_registrant *reg;
|
||||
int sk, asc;
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_SCSI, "PR OUT RELEASE: rkey 0x%"PRIx64", "
|
||||
"reservation type %u\n", rkey, rtype);
|
||||
|
||||
reg = spdk_scsi_pr_get_registrant(lun, task->initiator_port, task->target_port);
|
||||
if (!reg) {
|
||||
SPDK_ERRLOG("No registration\n");
|
||||
sk = SPDK_SCSI_SENSE_NOT_READY;
|
||||
asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
|
||||
goto check_condition;
|
||||
}
|
||||
|
||||
/* no reservation holder */
|
||||
if (!lun->reservation.holder) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_SCSI, "RELEASE: no reservation holder\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lun->reservation.rtype != rtype || rkey != lun->reservation.crkey) {
|
||||
sk = SPDK_SCSI_SENSE_ILLEGAL_REQUEST;
|
||||
asc = SPDK_SCSI_ASC_INVALID_FIELD_IN_CDB;
|
||||
goto check_condition;
|
||||
}
|
||||
|
||||
/* I_T nexus is not a persistent reservation holder */
|
||||
if (!spdk_scsi_pr_registrant_is_holder(lun, reg)) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_SCSI, "RELEASE: current I_T nexus is not holder\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
spdk_scsi_pr_release_reservation(lun, reg);
|
||||
|
||||
return 0;
|
||||
|
||||
check_condition:
|
||||
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION, sk, asc,
|
||||
SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
spdk_scsi_pr_out(struct spdk_scsi_task *task,
|
||||
uint8_t *cdb, uint8_t *data,
|
||||
@ -329,6 +377,12 @@ spdk_scsi_pr_out(struct spdk_scsi_task *task,
|
||||
rc = spdk_scsi_pr_out_reserve(task, rtype, rkey,
|
||||
spec_i_pt, all_tg_pt, aptpl);
|
||||
break;
|
||||
case SPDK_SCSI_PR_OUT_RELEASE:
|
||||
if (scope != SPDK_SCSI_PR_LU_SCOPE) {
|
||||
goto invalid;
|
||||
}
|
||||
rc = spdk_scsi_pr_out_release(task, rtype, rkey);
|
||||
break;
|
||||
default:
|
||||
SPDK_ERRLOG("Invalid service action code %u\n", action);
|
||||
goto invalid;
|
||||
|
Loading…
x
Reference in New Issue
Block a user