From 2b09903c2c5f4563ad756c156f3855785a62b359 Mon Sep 17 00:00:00 2001 From: Changpeng Liu Date: Tue, 14 May 2019 01:40:13 -0400 Subject: [PATCH] scsi: add persistent reservation in with read reservations support Change-Id: I5345207a6331889182324ae3231bb62c84b69d69 Signed-off-by: Changpeng Liu Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/436094 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto Reviewed-by: Paul Luse --- lib/scsi/scsi_pr.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/scsi/scsi_pr.c b/lib/scsi/scsi_pr.c index d49572995..09410ad11 100644 --- a/lib/scsi/scsi_pr.c +++ b/lib/scsi/scsi_pr.c @@ -586,6 +586,38 @@ spdk_scsi_pr_in_read_keys(struct spdk_scsi_task *task, uint8_t *data, return (sizeof(keys->header) + count * 8); } +static int +spdk_scsi_pr_in_read_reservations(struct spdk_scsi_task *task, + uint8_t *data, uint16_t data_len) +{ + struct spdk_scsi_lun *lun = task->lun; + struct spdk_scsi_pr_in_read_reservations_data *param; + bool all_regs = false; + + SPDK_DEBUGLOG(SPDK_LOG_SCSI, "PR IN READ RESERVATIONS\n"); + param = (struct spdk_scsi_pr_in_read_reservations_data *)(data); + + to_be32(¶m->header.pr_generation, lun->pr_generation); + if (lun->reservation.holder) { + all_regs = spdk_scsi_pr_is_all_registrants_type(lun); + if (all_regs) { + to_be64(¶m->rkey, 0); + } else { + to_be64(¶m->rkey, lun->reservation.crkey); + } + to_be32(¶m->header.addiontal_len, 16); + param->scope = SPDK_SCSI_PR_LU_SCOPE; + param->type = lun->reservation.rtype; + SPDK_DEBUGLOG(SPDK_LOG_SCSI, "READ RESERVATIONS with valid reservation\n"); + return sizeof(*param); + } + + /* no reservation */ + to_be32(¶m->header.addiontal_len, 0); + SPDK_DEBUGLOG(SPDK_LOG_SCSI, "READ RESERVATIONS no reservation\n"); + return sizeof(param->header); +} + int spdk_scsi_pr_in(struct spdk_scsi_task *task, uint8_t *cdb, uint8_t *data, @@ -603,6 +635,12 @@ spdk_scsi_pr_in(struct spdk_scsi_task *task, case SPDK_SCSI_PR_IN_READ_KEYS: rc = spdk_scsi_pr_in_read_keys(task, data, data_len); break; + case SPDK_SCSI_PR_IN_READ_RESERVATION: + if (data_len < sizeof(struct spdk_scsi_pr_in_read_reservations_data)) { + goto invalid; + } + rc = spdk_scsi_pr_in_read_reservations(task, data, data_len); + break; default: goto invalid; }